home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / unix / rcs.03 < prev    next >
Internet Message Format  |  1989-11-19  |  78KB

  1. Path: xanth!mcnc!uvaarpa!haven!ames!sun-barr!newstop!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i218:  rcs - revision control system, Part03/14
  5. Message-ID: <128094@sun.Eng.Sun.COM>
  6. Date: 19 Nov 89 09:24:26 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 2839
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: rsbx@cbmvax.commodore.com (Raymond S. Brand)
  12. Posting-number: Volume 89, Issue 218
  13. Archive-name: unix/rcs.03
  14.  
  15. # This is a shell archive.
  16. # Remove anything above and including the cut line.
  17. # Then run the rest of the file through 'sh'.
  18. # Unpacked files will be owned by you and have default permissions.
  19. #----cut here-----cut here-----cut here-----cut here----#
  20. #!/bin/sh
  21. # shar: SHell ARchive
  22. # Run the following text through 'sh' to create:
  23. #    diff/dir.c
  24. #    diff/ed.c
  25. #    diff/io.c
  26. #    diff/normal.c
  27. #    diff/regex.c
  28. # This is archive 3 of a 14-part kit.
  29. # This archive created: Sun Nov 19 01:12:05 1989
  30. if `test ! -d diff`
  31. then
  32.   mkdir diff
  33.   echo "mkdir diff"
  34. fi
  35. echo "extracting diff/dir.c"
  36. sed 's/^X//' << \SHAR_EOF > diff/dir.c
  37. X/* Read, sort and compare two directories.  Used for GNU DIFF.
  38. X   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  39. X
  40. XThis file is part of GNU DIFF.
  41. X
  42. XGNU DIFF is free software; you can redistribute it and/or modify
  43. Xit under the terms of the GNU General Public License as published by
  44. Xthe Free Software Foundation; either version 1, or (at your option)
  45. Xany later version.
  46. X
  47. XGNU DIFF is distributed in the hope that it will be useful,
  48. Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
  49. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  50. XGNU General Public License for more details.
  51. X
  52. XYou should have received a copy of the GNU General Public License
  53. Xalong with GNU DIFF; see the file COPYING.  If not, write to
  54. Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  55. X
  56. X#include "diff.h"
  57. X
  58. Xstatic int compare_names ();
  59. X
  60. X/* Read the directory named DIRNAME and return a sorted vector
  61. X   of filenames for its contents.  NONEX nonzero means this directory is
  62. X   known to be nonexistent, so return zero files.  */
  63. X
  64. Xstruct dirdata
  65. X{
  66. X  int length;            /* # elements in `files' */
  67. X  char **files;            /* Sorted names of files in the dir */
  68. X};
  69. X
  70. Xstatic struct dirdata
  71. Xdir_sort (dirname, nonex)
  72. X     char *dirname;
  73. X     int nonex;
  74. X{
  75. X  register DIR *reading;
  76. X  register struct direct *next;
  77. X  struct dirdata dirdata;
  78. X  int compare_names ();
  79. X
  80. X  /* Address of block containing the files that are described.  */
  81. X  char **files;
  82. X
  83. X  /* Length of block that `files' points to, measured in files.  */
  84. X  int nfiles;
  85. X
  86. X  /* Index of first unused in `files'.  */
  87. X  int files_index;
  88. X
  89. X  if (nonex)
  90. X    {
  91. X      dirdata.length = 0;
  92. X      dirdata.files = 0;
  93. X      return dirdata;
  94. X    }
  95. X
  96. X  /* Open the directory and check for errors.  */
  97. X  reading = opendir (dirname);
  98. X  if (!reading)
  99. X    {
  100. X      perror_with_name (dirname);
  101. X      dirdata.length = -1;
  102. X      return dirdata;
  103. X    }
  104. X
  105. X  /* Initialize the table of filenames.  */
  106. X
  107. X  nfiles = 100;
  108. X  files = (char **) xmalloc (nfiles * sizeof (char *));
  109. X  files_index = 0;
  110. X
  111. X  /* Read the directory entries, and insert the subfiles
  112. X     into the `files' table.  */
  113. X
  114. X  while (next = readdir (reading))
  115. X    {
  116. X      /* Ignore the files `.' and `..' */
  117. X      if (next->d_name[0] == '.'
  118. X      && (next->d_name[1] == 0
  119. X          || (next->d_name[1] == '.'
  120. X          && next->d_name[2] == 0)))
  121. X    continue;
  122. X
  123. X      if (files_index == nfiles)
  124. X    {
  125. X      nfiles *= 2;
  126. X      files
  127. X        = (char **) xrealloc (files, sizeof (char *) * nfiles);
  128. X    }
  129. X      files[files_index++] = concat (next->d_name, "", "");
  130. X    }
  131. X
  132. X  closedir (reading);
  133. X
  134. X  /* Sort the table.  */
  135. X  qsort (files, files_index, sizeof (char *), compare_names);
  136. X
  137. X  /* Return a description of location and length of the table.  */
  138. X  dirdata.files = files;
  139. X  dirdata.length = files_index;
  140. X
  141. X  return dirdata;
  142. X}
  143. X
  144. X/* Sort the files now in the table.  */
  145. X
  146. Xstatic int
  147. Xcompare_names (file1, file2)
  148. X     char **file1, **file2;
  149. X{
  150. X  return strcmp (*file1, *file2);
  151. X}
  152. X
  153. X/* Compare the contents of two directories named NAME1 and NAME2.
  154. X   This is a top-level routine; it does everything necessary for diff
  155. X   on two directories.
  156. X
  157. X   NONEX1 nonzero says directory NAME1 doesn't exist, but pretend it is
  158. X   empty.  Likewise NONEX2.
  159. X
  160. X   HANDLE_FILE is a caller-provided subroutine called to handle each file.
  161. X   It gets five operands: dir and name (rel to original working dir) of file
  162. X   in dir 1, dir and name pathname of file in dir 2, and the recursion depth.
  163. X
  164. X   For a file that appears in only one of the dirs, one of the name-args
  165. X   to HANDLE_FILE is zero.
  166. X
  167. X   DEPTH is the current depth in recursion.
  168. X
  169. X   Returns the maximum of all the values returned by HANDLE_FILE,
  170. X   or 2 if trouble is encountered in opening files.  */
  171. X
  172. Xint
  173. Xdiff_dirs (name1, name2, handle_file, depth, nonex1, nonex2)
  174. X     char *name1, *name2;
  175. X     int (*handle_file) ();
  176. X     int nonex1, nonex2;
  177. X{
  178. X  struct dirdata data1, data2;
  179. X  register int i1, i2;
  180. X  int val = 0;
  181. X  int v1;
  182. X
  183. X  /* Get sorted contents of both dirs.  */
  184. X  data1 = dir_sort (name1, nonex1);
  185. X  data2 = dir_sort (name2, nonex2);
  186. X  if (data1.length == -1 || data2.length == -1)
  187. X    {
  188. X      if (data1.length >= 0)
  189. X    free (data1.files);
  190. X      if (data2.length >= 0)
  191. X    free (data2.files);
  192. X      return 2;
  193. X    }
  194. X
  195. X  i1 = 0;
  196. X  i2 = 0;
  197. X
  198. X  /* If -Sname was specified, and this is the topmost level of comparison,
  199. X     ignore all file names less than the specified starting name.  */
  200. X
  201. X  if (dir_start_file && depth == 0)
  202. X    {
  203. X      while (i1 < data1.length && strcmp (data1.files[i1], dir_start_file) < 0)
  204. X    i1++;
  205. X      while (i2 < data2.length && strcmp (data2.files[i2], dir_start_file) < 0)
  206. X    i2++;
  207. X    }
  208. X
  209. X  /* Loop while files remain in one or both dirs.  */
  210. X  while (i1 < data1.length || i2 < data2.length)
  211. X    {
  212. X      int nameorder;
  213. X
  214. X      /* Compare next name in dir 1 with next name in dir 2.
  215. X     At the end of a dir,
  216. X     pretend the "next name" in that dir is very large.  */
  217. X
  218. X      if (i1 == data1.length)
  219. X    nameorder = 1;
  220. X      else if (i2 == data2.length)
  221. X    nameorder = -1;
  222. X      else
  223. X    nameorder = strcmp (data1.files[i1], data2.files[i2]);
  224. X
  225. X      if (nameorder == 0)
  226. X    {
  227. X      /* We have found a file (or subdir) in common between both dirs.
  228. X         Compare the two files.  */
  229. X      v1 = (*handle_file) (name1, data1.files[i1], name2, data2.files[i2],
  230. X                   depth + 1);
  231. X      i1++, i2++;
  232. X    }
  233. X      if (nameorder < 0)
  234. X    {
  235. X      /* Next filename in dir 1 is less; that is a file in dir 1 only.  */
  236. X      v1 = (*handle_file) (name1, data1.files[i1], name2, 0, depth + 1);
  237. X      i1++;
  238. X    }
  239. X      if (nameorder > 0)
  240. X    {
  241. X      /* Next filename in dir 2 is less; that is a file in dir 2 only.  */
  242. X      v1 = (*handle_file) (name1, 0, name2, data2.files[i2], depth + 1);
  243. X      i2++;
  244. X    }
  245. X      if (v1 > val)
  246. X    val = v1;
  247. X    }
  248. X  free (data1.files);
  249. X  free (data2.files);
  250. X
  251. X  return val;
  252. X}
  253. SHAR_EOF
  254. echo "extracting diff/ed.c"
  255. sed 's/^X//' << \SHAR_EOF > diff/ed.c
  256. X/* Output routines for ed-script format.
  257. X   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  258. X
  259. XThis file is part of GNU DIFF.
  260. X
  261. XGNU DIFF is free software; you can redistribute it and/or modify
  262. Xit under the terms of the GNU General Public License as published by
  263. Xthe Free Software Foundation; either version 1, or (at your option)
  264. Xany later version.
  265. X
  266. XGNU DIFF is distributed in the hope that it will be useful,
  267. Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
  268. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  269. XGNU General Public License for more details.
  270. X
  271. XYou should have received a copy of the GNU General Public License
  272. Xalong with GNU DIFF; see the file COPYING.  If not, write to
  273. Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  274. X
  275. X#include "diff.h"
  276. X
  277. Xstatic void print_rcs_hunk ();
  278. Xstatic void print_ed_hunk ();
  279. Xstatic void pr_forward_ed_hunk ();
  280. Xstatic void print_range_length ();
  281. Xvoid translate_range ();
  282. Xstruct change *find_change ();
  283. Xstruct change *find_reverse_change ();
  284. X
  285. X/* Print our script as ed commands.  */
  286. X
  287. Xvoid
  288. Xprint_ed_script (script)
  289. X    struct change *script;
  290. X{
  291. X  print_script (script, find_reverse_change, print_ed_hunk);
  292. X}
  293. X
  294. X/* Print a hunk of an ed diff */
  295. X
  296. Xstatic void
  297. Xprint_ed_hunk (hunk)
  298. X     struct change *hunk; 
  299. X{
  300. X  int f0, l0, f1, l1;
  301. X  int deletes, inserts;
  302. X
  303. X#if 0
  304. X  hunk = flip_script (hunk);
  305. X#endif
  306. X#ifdef MYDEBUG
  307. X  debug_script (hunk);
  308. X#endif
  309. X
  310. X  /* Determine range of line numbers involved in each file.  */
  311. X  analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
  312. X  if (!deletes && !inserts)
  313. X    return;
  314. X
  315. X  /* Print out the line number header for this hunk */
  316. X  print_number_range (',', &files[0], f0, l0);
  317. X  fprintf (outfile, "%c\n", change_letter (inserts, deletes));
  318. X
  319. X  /* Print new/changed lines from second file, if needed */
  320. X  if (inserts)
  321. X    {
  322. X      int i;
  323. X      int inserting = 1;
  324. X      for (i = f1; i <= l1; i++)
  325. X    {
  326. X      /* Resume the insert, if we stopped.  */
  327. X      if (! inserting)
  328. X        fprintf (outfile, "%da\n",
  329. X             i - f1 + translate_line_number (&files[0], f0) - 1);
  330. X      inserting = 1;
  331. X
  332. X      /* If the file's line is just a dot, it would confuse `ed'.
  333. X         So output it with a double dot, and set the flag LEADING_DOT
  334. X         so that we will output another ed-command later
  335. X         to change the double dot into a single dot.  */
  336. X
  337. X      if (files[1].linbuf[i].text[0] == '.'
  338. X          && files[1].linbuf[i].text[1] == '\n')
  339. X        {
  340. X          fprintf (outfile, "..\n");
  341. X          fprintf (outfile, ".\n");
  342. X          /* Now change that double dot to the desired single dot.  */
  343. X          fprintf (outfile, "%ds/^\\.\\././\n",
  344. X               i - f1 + translate_line_number (&files[0], f0));
  345. X          inserting = 0;
  346. X        }
  347. X      else
  348. X        /* Line is not `.', so output it unmodified.  */
  349. X        print_1_line ("", &files[1].linbuf[i]);
  350. X    }
  351. X
  352. X      /* End insert mode, if we are still in it.  */
  353. X      if (inserting)
  354. X    fprintf (outfile, ".\n");
  355. X    }
  356. X}
  357. X
  358. X/* Print change script in the style of ed commands,
  359. X   but print the changes in the order they appear in the input files,
  360. X   which means that the commands are not truly useful with ed.  */
  361. X
  362. Xvoid
  363. Xpr_forward_ed_script (script)
  364. X     struct change *script;
  365. X{
  366. X  print_script (script, find_change, pr_forward_ed_hunk);
  367. X}
  368. X
  369. Xstatic void
  370. Xpr_forward_ed_hunk (hunk)
  371. X     struct change *hunk;
  372. X{
  373. X  int i;
  374. X  int f0, l0, f1, l1;
  375. X  int deletes, inserts;
  376. X
  377. X  /* Determine range of line numbers involved in each file.  */
  378. X  analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
  379. X  if (!deletes && !inserts)
  380. X    return;
  381. X
  382. X  fprintf (outfile, "%c", change_letter (inserts, deletes));
  383. X  print_number_range (' ', files, f0, l0);
  384. X  fprintf (outfile, "\n");
  385. X
  386. X  /* If deletion only, print just the number range.  */
  387. X
  388. X  if (!inserts)
  389. X    return;
  390. X
  391. X  /* For insertion (with or without deletion), print the number range
  392. X     and the lines from file 2.  */
  393. X
  394. X  for (i = f1; i <= l1; i++)
  395. X    print_1_line ("", &files[1].linbuf[i]);
  396. X
  397. X  fprintf (outfile, ".\n");
  398. X}
  399. X
  400. X/* Print in a format somewhat like ed commands
  401. X   except that each insert command states the number of lines it inserts.
  402. X   This format is used for RCS.  */
  403. X
  404. Xvoid
  405. Xprint_rcs_script (script)
  406. X     struct change *script;
  407. X{
  408. X  print_script (script, find_change, print_rcs_hunk);
  409. X}
  410. X
  411. X/* Print a hunk of an RCS diff */
  412. X
  413. Xstatic void
  414. Xprint_rcs_hunk (hunk)
  415. X     struct change *hunk;
  416. X{
  417. X  int i;
  418. X  int f0, l0, f1, l1;
  419. X  int deletes, inserts;
  420. X  int tf0, tl0, tf1, tl1;
  421. X
  422. X  /* Determine range of line numbers involved in each file.  */
  423. X  analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
  424. X  if (!deletes && !inserts)
  425. X    return;
  426. X
  427. X  translate_range (&files[0], f0, l0, &tf0, &tl0);
  428. X
  429. X  if (deletes)
  430. X    {
  431. X      fprintf (outfile, "d");
  432. X      /* For deletion, print just the starting line number from file 0
  433. X     and the number of lines deleted.  */
  434. X      fprintf (outfile, "%d %d\n",
  435. X           tf0,
  436. X           (tl0 >= tf0 ? tl0 - tf0 + 1 : 1));         
  437. X    }
  438. X
  439. X  if (inserts)
  440. X    {
  441. X      fprintf (outfile, "a");
  442. X
  443. X      /* Take last-line-number from file 0 and # lines from file 1.  */
  444. X      translate_range (&files[1], f1, l1, &tf1, &tl1);
  445. X      fprintf (outfile, "%d %d\n",
  446. X           tl0,
  447. X           (tl1 >= tf1 ? tl1 - tf1 + 1 : 1));         
  448. X
  449. X      /* Print the inserted lines.  */
  450. X      for (i = f1; i <= l1; i++)
  451. X    print_1_line ("", &files[1].linbuf[i]);
  452. X    }
  453. X}
  454. SHAR_EOF
  455. echo "extracting diff/io.c"
  456. sed 's/^X//' << \SHAR_EOF > diff/io.c
  457. X/* File I/O for GNU DIFF.
  458. X   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  459. X
  460. XThis file is part of GNU DIFF.
  461. X
  462. XGNU DIFF is free software; you can redistribute it and/or modify
  463. Xit under the terms of the GNU General Public License as published by
  464. Xthe Free Software Foundation; either version 1, or (at your option)
  465. Xany later version.
  466. X
  467. XGNU DIFF is distributed in the hope that it will be useful,
  468. Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
  469. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  470. XGNU General Public License for more details.
  471. X
  472. XYou should have received a copy of the GNU General Public License
  473. Xalong with GNU DIFF; see the file COPYING.  If not, write to
  474. Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  475. X
  476. X#include "diff.h"
  477. X
  478. X/* Rotate a value n bits to the left. */
  479. X#define UINT_BIT (sizeof (unsigned) * CHAR_BIT)
  480. X#define ROL(v, n) ((v) << (n) | (v) >> UINT_BIT - (n))
  481. X
  482. X/* Given a hash value and a new character, return a new hash value. */
  483. X#define HASH(h, c) ((c) + ROL (h, 7))
  484. X
  485. X/* Current file under consideration. */
  486. Xstruct file_data *current;
  487. X
  488. X/* Check for binary files and compare them for exact identity.  */
  489. X
  490. X/* Return 1 if BUF contains a character with the 0200 bit set.
  491. X   SIZE is the number of characters in BUF.  */
  492. X
  493. Xstatic int
  494. Xbinary_file_p (buf, size)
  495. X     char *buf;
  496. X     int size;
  497. X{
  498. X  while (--size >= 0)
  499. X    if (*buf++ & 0200)
  500. X      return 1;
  501. X  return 0;
  502. X}
  503. X
  504. Xint binary_file_threshold = 512;
  505. X
  506. X/* Slurp the current file completely into core.
  507. X   Return nonzero if it appears to be a binary file.  */
  508. X
  509. Xstatic int
  510. Xslurp ()
  511. X{
  512. X  /* If we have a nonexistent file at this stage, treat it as empty.  */
  513. X  if (current->desc < 0)
  514. X    {
  515. X      current->bufsize = 0;
  516. X      current->buffered_chars = 0;
  517. X      current->buffer = 0;
  518. X    }
  519. X  /* If it's a regular file, we can just get the size out of the stat
  520. X     block and slurp it in all at once. */
  521. X  /* In all cases, we leave room in the buffer for 2 extra chars
  522. X     beyond those that current->bufsize describes:
  523. X     one for a newline (in case the text does not end with one)
  524. X     and one for a sentinel in find_identical_ends.  */
  525. X#ifdef AMIGA
  526. X  else if (current->stat.st_type < 0)
  527. X#else
  528. X  else if ((current->stat.st_mode & S_IFMT) == S_IFREG)
  529. X#endif
  530. X    {
  531. X      current->bufsize = current->stat.st_size;
  532. X      current->buffer = (char *) xmalloc (current->bufsize + 2);
  533. X      current->buffered_chars
  534. X    = read (current->desc, current->buffer, current->bufsize);
  535. X      if (current->buffered_chars < 0)
  536. X    pfatal_with_name (current->name);
  537. X    }
  538. X  else
  539. X    {
  540. X      int cc;
  541. X
  542. X      current->bufsize = 4096;
  543. X      current->buffer = (char *) xmalloc (current->bufsize + 2);
  544. X      current->buffered_chars = 0;
  545. X      
  546. X      /* Not a regular file; read it in a little at a time, growing the
  547. X     buffer as necessary. */
  548. X      while ((cc = read (current->desc,
  549. X             current->buffer + current->buffered_chars,
  550. X             current->bufsize - current->buffered_chars))
  551. X         > 0)
  552. X    {
  553. X      current->buffered_chars += cc;
  554. X      if (current->buffered_chars == current->bufsize)
  555. X        {
  556. X          current->bufsize = current->bufsize * 2;
  557. X          current->buffer = (char *) xrealloc (current->buffer,
  558. X                           current->bufsize + 2);
  559. X        }
  560. X    }
  561. X      if (cc < 0)
  562. X    pfatal_with_name (current->name);
  563. X    }
  564. X  
  565. X  /* Check first part of file to see if it's a binary file.  */
  566. X  if (! always_text_flag
  567. X      && binary_file_p (current->buffer,
  568. X            min (current->buffered_chars, binary_file_threshold)))
  569. X    return 1;
  570. X
  571. X  /* If not binary, make sure text ends in a newline,
  572. X     but remember that we had to add one.  */
  573. X  if (current->buffered_chars > 0
  574. X      && current->buffer[current->buffered_chars - 1] != '\n')
  575. X    {
  576. X      current->missing_newline = 1;
  577. X      current->buffer[current->buffered_chars++] = '\n';
  578. X    }
  579. X  else
  580. X    current->missing_newline = 0;
  581. X
  582. X  return 0;
  583. X}
  584. X
  585. X/* Split the file into lines, simultaneously computing the hash codes for
  586. X   each line. */
  587. X
  588. Xvoid
  589. Xfind_and_hash_each_line ()
  590. X{
  591. X  unsigned h;
  592. X  int i;
  593. X  unsigned char *p = (unsigned char *) current->prefix_end, *ip, c;
  594. X
  595. X  /* Attempt to get a good initial guess as to the number of lines. */
  596. X  current->linbufsize = current->buffered_chars / 50 + 5;
  597. X  current->linbuf
  598. X    = (struct line_def *) xmalloc (current->linbufsize * sizeof (struct line_def));
  599. X
  600. X  if (function_regexp)
  601. X    {
  602. X      /* If the -C or -F option is used, we need to find the lines
  603. X     of the matching prefix.  At least we will need to find the last few,
  604. X     but since we don't know how many, it's easiest to find them all.  */
  605. X      current->buffered_lines = 0;
  606. X      p = (unsigned char *) current->buffer;
  607. X    }
  608. X  else
  609. X    {
  610. X      /* Skip the identical prefixes, except be prepared to handle context.
  611. X     In fact, handle 1 more preceding line than the context says,
  612. X     in case shift_boundaries moves things backwards in this file.  */
  613. X      current->buffered_lines = current->prefix_lines - context - 1;
  614. X      if (current->buffered_lines < 0)
  615. X    current->buffered_lines = 0;
  616. X      for (i = 0; i < context + 1; ++i)
  617. X    /* Unless we are at the beginning, */
  618. X    if ((char *) p != current->buffer)
  619. X      /* Back up at least 1 char until at the start of a line.  */
  620. X      while ((char *) --p != current->buffer && p[-1] != '\n')
  621. X        ;
  622. X    }
  623. X
  624. X  while ((char *) p < current->suffix_begin)
  625. X    {
  626. X      h = 0;
  627. X      ip = p;
  628. X
  629. X      if (current->prefix_end <= (char *) p)
  630. X    {
  631. X      /* Hash this line until we find a newline. */
  632. X      if (ignore_case_flag)
  633. X        {
  634. X          if (ignore_all_space_flag)
  635. X        while ((c = *p) != '\n')
  636. X          {
  637. X            if (! isspace (c))
  638. X              if (isupper (c))
  639. X            h = HASH (h, tolower (c));
  640. X              else
  641. X            h = HASH (h, c);
  642. X            ++p;
  643. X          }
  644. X          else if (ignore_space_change_flag)
  645. X
  646. X        while ((c = *p) != '\n')
  647. X          {
  648. X            if (c == ' ' || c == '\t')
  649. X              {
  650. X            while ((c = *p) == ' ' || c == '\t')
  651. X              ++p;
  652. X            if (c == '\n')
  653. X              break;
  654. X            h = HASH (h, ' ');
  655. X              }
  656. X            else if (isupper (c))
  657. X              h = HASH (h, tolower (c));
  658. X            else
  659. X              h = HASH (h, c);
  660. X            ++p;
  661. X          }
  662. X          else
  663. X        while ((c = *p) != '\n')
  664. X          {
  665. X            if (isupper (c))
  666. X              h = HASH (h, tolower (c));
  667. X            else
  668. X              h = HASH (h, c);
  669. X            ++p;
  670. X          }
  671. X        }
  672. X      else
  673. X        {
  674. X          if (ignore_all_space_flag)
  675. X        while ((c = *p) != '\n')
  676. X          {
  677. X            if (! isspace (c))
  678. X              h = HASH (h, c);
  679. X            ++p;
  680. X          }
  681. X          else if (ignore_space_change_flag)
  682. X        while ((c = *p) != '\n')
  683. X          {
  684. X            if (c == ' ' || c == '\t')
  685. X              {
  686. X            while ((c = *p) == ' ' || c == '\t')
  687. X              ++p;
  688. X            if (c == '\n')
  689. X              break;
  690. X            h = HASH (h, ' ');
  691. X              }
  692. X            else
  693. X              h = HASH (h, c);
  694. X            ++p;
  695. X          }
  696. X          else
  697. X        while ((c = *p) != '\n')
  698. X          {
  699. X            h = HASH (h, c);
  700. X            ++p;
  701. X          }
  702. X        }
  703. X    }
  704. X      else
  705. X    /* This line is part of the matching prefix,
  706. X       so we don't need to hash it.  */
  707. X    while (*p != '\n')
  708. X      ++p;
  709. X      
  710. X      /* Maybe increase the size of the line table. */
  711. X      if (current->buffered_lines >= current->linbufsize)
  712. X    {
  713. X      while (current->buffered_lines >= current->linbufsize)
  714. X        current->linbufsize *= 2;
  715. X      current->linbuf
  716. X        = (struct line_def *) xrealloc (current->linbuf,
  717. X                        current->linbufsize
  718. X                        * sizeof (struct line_def));
  719. X    }
  720. X      current->linbuf[current->buffered_lines].text = (char *) ip;
  721. X      current->linbuf[current->buffered_lines].length = p - ip;
  722. X      current->linbuf[current->buffered_lines].hash = h;
  723. X      ++current->buffered_lines;
  724. X      ++p;
  725. X    }
  726. X
  727. X  i = 0;
  728. X  while (i < context && (char *) p < current->buffer + current->buffered_chars)
  729. X    {
  730. X      ip = p;
  731. X      while (*p++ != '\n')
  732. X    ;
  733. X      /* Maybe increase the size of the line table. */
  734. X      if (current->buffered_lines >= current->linbufsize)
  735. X    {
  736. X      while (current->buffered_lines >= current->linbufsize)
  737. X        current->linbufsize *= 2;
  738. X      current->linbuf
  739. X        = (struct line_def *) xrealloc (current->linbuf,
  740. X                        current->linbufsize
  741. X                        * sizeof (struct line_def));
  742. X    }
  743. X      current->linbuf[current->buffered_lines].text = (char *) ip;
  744. X      current->linbuf[current->buffered_lines].length = p - ip - 1;
  745. X      current->linbuf[current->buffered_lines].hash = 0;
  746. X      ++current->buffered_lines;
  747. X      ++i;
  748. X    }
  749. X}
  750. X
  751. X/* Given a vector of two file_data objects, find the identical
  752. X   prefixes and suffixes of each object. */
  753. X
  754. Xstatic void
  755. Xfind_identical_ends (filevec)
  756. X     struct file_data filevec[];
  757. X{
  758. X  char *p0, *p1, *end0, *beg0;
  759. X  int lines;
  760. X
  761. X  if (filevec[0].buffered_chars == 0 || filevec[1].buffered_chars == 0)
  762. X    {
  763. X      filevec[0].prefix_end = filevec[0].buffer;
  764. X      filevec[1].prefix_end = filevec[1].buffer;
  765. X      filevec[0].prefix_lines = filevec[1].prefix_lines = 0;
  766. X      filevec[0].suffix_begin = filevec[0].buffer + filevec[0].buffered_chars;
  767. X      filevec[1].suffix_begin = filevec[1].buffer + filevec[1].buffered_chars;
  768. X      filevec[0].suffix_lines = filevec[1].suffix_lines = 0;
  769. X      return;
  770. X    }
  771. X
  772. X  /* Find identical prefix.  */
  773. X
  774. X  p0 = filevec[0].buffer;
  775. X  p1 = filevec[1].buffer;
  776. X  lines = 0;
  777. X
  778. X  /* Insert end "sentinels", in this case characters that are guarranteed
  779. X     to make the equality test false, and thus terminate the loop.  */
  780. X
  781. X  if (filevec[0].buffered_chars < filevec[1].buffered_chars)
  782. X    p0[filevec[0].buffered_chars] = ~p1[filevec[0].buffered_chars];
  783. X  else
  784. X    p1[filevec[1].buffered_chars] = ~p0[filevec[1].buffered_chars];
  785. X
  786. X  /* Loop until first mismatch, or to the sentinel characters.  */
  787. X  while (1)
  788. X    {
  789. X      char c = *p0++;
  790. X      if (c != *p1++)
  791. X    break;
  792. X      if (c == '\n')
  793. X    ++lines;
  794. X    }
  795. X
  796. X  /* If the sentinel was passed, and lengths are equal, the
  797. X     files are identical.  */
  798. X  if (p0 - filevec[0].buffer > filevec[0].buffered_chars
  799. X      && filevec[0].buffered_chars == filevec[1].buffered_chars)
  800. X    {
  801. X      filevec[0].prefix_end = p0 - 1;
  802. X      filevec[1].prefix_end = p1 - 1;
  803. X      filevec[0].prefix_lines = filevec[1].prefix_lines = lines;
  804. X      filevec[0].suffix_begin = filevec[0].buffer;
  805. X      filevec[1].suffix_begin = filevec[1].buffer;
  806. X      filevec[0].suffix_lines = filevec[1].suffix_lines = lines;
  807. X      return;
  808. X    }
  809. X
  810. X  /* Point at first nonmatching characters.  */
  811. X  --p0, --p1;
  812. X
  813. X  /* Skip back to last line-beginning in the prefix.  */
  814. X  while (p0 != filevec[0].buffer && p0[-1] != '\n')
  815. X    --p0, --p1;
  816. X
  817. X  /* Record the prefix.  */
  818. X  filevec[0].prefix_end = p0;
  819. X  filevec[1].prefix_end = p1;
  820. X  filevec[0].prefix_lines = filevec[1].prefix_lines = lines;
  821. X  
  822. X  /* Find identical suffix.  */
  823. X
  824. X  /* P0 and P1 point beyond the last chars not yet compared.  */
  825. X  p0 = filevec[0].buffer + filevec[0].buffered_chars;
  826. X  p1 = filevec[1].buffer + filevec[1].buffered_chars;
  827. X  lines = 0;
  828. X  end0 = p0;        /* Addr of last char in file 0.  */
  829. X
  830. X  /* Get value of P0 at which we should stop scanning backward:
  831. X     this is when either P0 or P1 points at the last char
  832. X     of the identical prefix.  */
  833. X  if (filevec[0].buffered_chars < filevec[1].buffered_chars)
  834. X    beg0 = filevec[0].prefix_end - 1;
  835. X  else
  836. X    beg0 = (filevec[0].prefix_end - 1
  837. X        + filevec[1].buffered_chars - filevec[0].buffered_chars);
  838. X
  839. X  /* Scan back until chars don't match or we reach that point.  */
  840. X  while (p0 != beg0)
  841. X    {
  842. X      char c = *--p0;
  843. X      if (c != *--p1)
  844. X    break;
  845. X      if (c == '\n')
  846. X    ++lines;
  847. X    }
  848. X
  849. X  /* Make P0 and P1 point at the first char of the matching suffix.  */
  850. X  ++p0, ++p1;
  851. X
  852. X  /* Advance to next place that is a line-beginning in both files.  */
  853. X  while (p0 != end0
  854. X     && !((p0 == filevec[0].buffer || p0[-1] == '\n')
  855. X          &&
  856. X          (p1 == filevec[1].buffer || p1[-1] == '\n')))
  857. X    ++p0, ++p1;
  858. X
  859. X  /* Subtract one, since the last newline isn't followed by a line.  */
  860. X  --lines;
  861. X  
  862. X  /* Record the suffix.  */
  863. X  filevec[0].suffix_begin = p0;
  864. X  filevec[1].suffix_begin = p1;
  865. X  filevec[0].suffix_lines = filevec[1].suffix_lines = lines;
  866. X}
  867. X
  868. X/* Lines are put into equivalence classes (of lines that match in line_cmp).
  869. X   Each equivalence class is represented by one of these structures,
  870. X   but only while the classes are being computed.
  871. X   Afterward, each class is represented by a number.  */
  872. Xstruct equivclass
  873. X{
  874. X  struct equivclass *next;    /* Next item in this bucket. */
  875. X  struct line_def line;    /* A line that fits this class. */
  876. X};
  877. X
  878. X/* Hash-table: array of buckets, each being a chain of equivalence classes.  */
  879. Xstatic struct equivclass **buckets;
  880. X  
  881. X/* Size of the bucket array. */
  882. Xstatic int nbuckets;
  883. X
  884. X/* Array in which the equivalence classes are allocated.
  885. X   The bucket-chains go through the elements in this array.
  886. X   The number of an equivalence class is its index in this array.  */
  887. Xstatic struct equivclass *equivs;
  888. X
  889. X/* Index of first free element in the array `equivs'.  */
  890. Xstatic int equivs_index;
  891. X
  892. X/* Size allocated to the array `equivs'.  */
  893. Xstatic int equivs_alloc;
  894. X
  895. X/* Largest primes less than some power of two, for nbuckets.  Values range
  896. X   from useful to preposterous.  If one of these numbers isn't prime
  897. X   after all, don't blame it on me, blame it on primes (6) . . . */
  898. Xstatic int primes[] =
  899. X{
  900. X  509,
  901. X  1021,
  902. X  2039,
  903. X  4093,
  904. X  8191,
  905. X  16381,
  906. X  32749,
  907. X  65521,
  908. X  131071,
  909. X  262139,
  910. X  524287,
  911. X  1048573,
  912. X  2097143,
  913. X  4194301,
  914. X  8388593,
  915. X  16777213,
  916. X  33554393,
  917. X  67108859,            /* Preposterously large . . . */
  918. X  -1
  919. X};
  920. X
  921. X/* Index of current nbuckets in primes. */
  922. Xstatic int primes_index;
  923. X
  924. X/* Find the equiv class associated with line N of the current file.  */
  925. X
  926. Xstatic int
  927. Xfind_equiv_class (n)
  928. X     int n;
  929. X{
  930. X  int bucket = current->linbuf[n].hash % nbuckets;
  931. X  struct equivclass *b = buckets[bucket], *p = NULL;
  932. X
  933. X  /* Equivalence class 0 is permanently allocated to lines that were
  934. X     not hashed because they were parts of identical prefixes or
  935. X     suffixes. */
  936. X  if (n < current->prefix_lines
  937. X      || current->linbuf[n].text >= current->suffix_begin)
  938. X    return 0;
  939. X
  940. X  /* Check through the appropriate bucket to see if there isn't already
  941. X     an equivalence class for this line. */
  942. X  while (b)
  943. X    {
  944. X      if (b->line.hash == current->linbuf[n].hash
  945. X      && (b->line.length == current->linbuf[n].length
  946. X          /* Lines of different lengths can match with certain options.  */
  947. X          || length_varies)
  948. X      && !line_cmp (&b->line, ¤t->linbuf[n]))
  949. X    return b - equivs;
  950. X      p = b, b = b->next;
  951. X    }
  952. X
  953. X  /* Create a new equivalence class in this bucket. */
  954. X
  955. X  p = &equivs[equivs_index++];
  956. X  p->next = buckets[bucket];
  957. X  buckets[bucket] = p;
  958. X  p->line = current->linbuf[n];
  959. X
  960. X  return equivs_index - 1;
  961. X}
  962. X
  963. X/* Given a vector of two file_data objects, read the file associated
  964. X   with each one, and build the table of equivalence classes.
  965. X   Return nonzero if either file appears to be a binary file.  */
  966. X
  967. Xint
  968. Xread_files (filevec)
  969. X     struct file_data filevec[];
  970. X{
  971. X  int i, j;
  972. X  int binary = 0;
  973. X  int this_binary;
  974. X
  975. X  current = &filevec[0];
  976. X  binary = this_binary = slurp ();
  977. X
  978. X  current = &filevec[1];
  979. X  this_binary = slurp ();
  980. X  if (binary || this_binary)
  981. X    return 1;
  982. X
  983. X  find_identical_ends (filevec);
  984. X
  985. X  for (i = 0; i < 2; ++i)
  986. X    {
  987. X      current = &filevec[i];
  988. X      find_and_hash_each_line ();
  989. X    }
  990. X
  991. X  /* This is guaranteed to be enough space.  */
  992. X  equivs_alloc = filevec[0].buffered_lines + filevec[1].buffered_lines + 1;
  993. X  equivs = (struct equivclass *) xmalloc (equivs_alloc * sizeof (struct equivclass));
  994. X  /* Equivalence class 0 is permanently safe for lines that were not
  995. X     hashed.  Real equivalence classes start at 1. */
  996. X  equivs_index = 1;
  997. X  
  998. X  primes_index = 0;
  999. X  while (primes[primes_index] < equivs_alloc / 3)
  1000. X    primes_index++;
  1001. X
  1002. X  buckets = (struct equivclass **) xmalloc (primes[primes_index] * sizeof (struct equivclass *));
  1003. X  bzero (buckets, primes[primes_index] * sizeof (struct equivclass *));
  1004. X  nbuckets = primes[primes_index];
  1005. X
  1006. X  for (i = 0; i < 2; ++i)
  1007. X    {
  1008. X      current = &filevec[i];
  1009. X      current->equivs
  1010. X    = (int *) xmalloc (current->buffered_lines * sizeof (int));
  1011. X      for (j = 0; j < current->buffered_lines; ++j)
  1012. X    current->equivs[j] = find_equiv_class (j);
  1013. X    }
  1014. X
  1015. X  filevec[0].equiv_max = filevec[1].equiv_max = equivs_index;
  1016. X
  1017. X  free (equivs);
  1018. X  free (buckets);
  1019. X
  1020. X  return 0;
  1021. X}
  1022. SHAR_EOF
  1023. echo "extracting diff/normal.c"
  1024. sed 's/^X//' << \SHAR_EOF > diff/normal.c
  1025. X/* Normal-format output routines for GNU DIFF.
  1026. X   Copyright (C) 1988, 1989 Free Software Foundation, Inc.
  1027. X
  1028. XThis file is part of GNU DIFF.
  1029. X
  1030. XGNU DIFF is free software; you can redistribute it and/or modify
  1031. Xit under the terms of the GNU General Public License as published by
  1032. Xthe Free Software Foundation; either version 1, or (at your option)
  1033. Xany later version.
  1034. X
  1035. XGNU DIFF is distributed in the hope that it will be useful,
  1036. Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
  1037. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1038. XGNU General Public License for more details.
  1039. X
  1040. XYou should have received a copy of the GNU General Public License
  1041. Xalong with GNU DIFF; see the file COPYING.  If not, write to
  1042. Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  1043. X
  1044. X
  1045. X#include "diff.h"
  1046. X
  1047. Xvoid print_normal_hunk ();
  1048. Xvoid print_number_range ();
  1049. Xstruct change *find_change ();
  1050. X
  1051. X/* Print the edit-script SCRIPT as a normal diff.
  1052. X   INF points to an array of descriptions of the two files.  */
  1053. X
  1054. Xvoid
  1055. Xprint_normal_script (script)
  1056. X     struct change *script;
  1057. X{
  1058. X  print_script (script, find_change, print_normal_hunk);
  1059. X}
  1060. X
  1061. X/* Print a hunk of a normal diff.
  1062. X   This is a contiguous portion of a complete edit script,
  1063. X   describing changes in consecutive lines.  */
  1064. X
  1065. Xvoid
  1066. Xprint_normal_hunk (hunk)
  1067. X     struct change *hunk;
  1068. X{
  1069. X  int first0, last0, first1, last1, deletes, inserts;
  1070. X  register int i;
  1071. X
  1072. X  /* Determine range of line numbers involved in each file.  */
  1073. X  analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts);
  1074. X  if (!deletes && !inserts)
  1075. X    return;
  1076. X
  1077. X  /* Print out the line number header for this hunk */
  1078. X  print_number_range (',', &files[0], first0, last0);
  1079. X  fprintf (outfile, "%c", change_letter (inserts, deletes));
  1080. X  print_number_range (',', &files[1], first1, last1);
  1081. X  fprintf (outfile, "\n");
  1082. X
  1083. X  /* Print the lines that the first file has.  */
  1084. X  if (deletes)
  1085. X    for (i = first0; i <= last0; i++)
  1086. X      print_1_line ("<", &files[0].linbuf[i]);
  1087. X
  1088. X  if (inserts && deletes)
  1089. X    fprintf (outfile, "---\n");
  1090. X
  1091. X  /* Print the lines that the second file has.  */
  1092. X  if (inserts)
  1093. X    for (i = first1; i <= last1; i++)
  1094. X      print_1_line (">", &files[1].linbuf[i]);
  1095. X}
  1096. SHAR_EOF
  1097. echo "extracting diff/regex.c"
  1098. sed 's/^X//' << \SHAR_EOF > diff/regex.c
  1099. X/* Extended regular expression matching and search library.
  1100. X   Copyright (C) 1985, 1989 Free Software Foundation, Inc.
  1101. X
  1102. X   This program is free software; you can redistribute it and/or modify
  1103. X   it under the terms of the GNU General Public License as published by
  1104. X   the Free Software Foundation; either version 1, or (at your option)
  1105. X   any later version.
  1106. X
  1107. X   This program is distributed in the hope that it will be useful,
  1108. X   but WITHOUT ANY WARRANTY; without even the implied warranty of
  1109. X   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1110. X   GNU General Public License for more details.
  1111. X
  1112. X   You should have received a copy of the GNU General Public License
  1113. X   along with this program; if not, write to the Free Software
  1114. X   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1115. X
  1116. X
  1117. X   In other words, you are welcome to use, share and improve this program.
  1118. X   You are forbidden to forbid anyone else to use, share and improve
  1119. X   what you give them.   Help stamp out software-hoarding!  */
  1120. X
  1121. X
  1122. X/* To test, compile with -Dtest.
  1123. X This Dtestable feature turns this into a self-contained program
  1124. X which reads a pattern, describes how it compiles,
  1125. X then reads a string and searches for it.  */
  1126. X
  1127. X#ifdef AMIGA
  1128. X#define bcmp(a,b,l) memcmp(a,b,l)
  1129. X#define bcopy(f,t,l) movmem(f,t,l)
  1130. X#define bzero(a,l) memset(a,'0',l)
  1131. X#define alloca(n) malloc(n)
  1132. X#endif
  1133. X
  1134. X#ifdef emacs
  1135. X
  1136. X/* The `emacs' switch turns on certain special matching commands
  1137. X that make sense only in emacs. */
  1138. X
  1139. X#include "config.h"
  1140. X#include "lisp.h"
  1141. X#include "buffer.h"
  1142. X#include "syntax.h"
  1143. X
  1144. X#else  /* not emacs */
  1145. X
  1146. X#ifdef USG
  1147. X#ifndef BSTRING
  1148. X#define bcopy(s,d,n)    memcpy((d),(s),(n))
  1149. X#define bcmp(s1,s2,n)    memcmp((s1),(s2),(n))
  1150. X#define bzero(s,n)    memset((s),0,(n))
  1151. X#endif
  1152. X#endif
  1153. X
  1154. X/* Make alloca work the best possible way.  */
  1155. X#ifdef __GNUC__
  1156. X#define alloca __builtin_alloca
  1157. X#else
  1158. X#ifdef sparc
  1159. X#include <alloca.h>
  1160. X#endif
  1161. X#endif
  1162. X
  1163. X/*
  1164. X * Define the syntax stuff, so we can do the \<...\> things.
  1165. X */
  1166. X
  1167. X#ifndef Sword /* must be non-zero in some of the tests below... */
  1168. X#define Sword 1
  1169. X#endif
  1170. X
  1171. X#define SYNTAX(c) re_syntax_table[c]
  1172. X
  1173. X#ifdef SYNTAX_TABLE
  1174. X
  1175. Xchar *re_syntax_table;
  1176. X
  1177. X#else
  1178. X
  1179. Xstatic char re_syntax_table[256];
  1180. X
  1181. Xstatic void
  1182. Xinit_syntax_once ()
  1183. X{
  1184. X   register int c;
  1185. X   static int done = 0;
  1186. X
  1187. X   if (done)
  1188. X     return;
  1189. X
  1190. X   bzero (re_syntax_table, sizeof re_syntax_table);
  1191. X
  1192. X   for (c = 'a'; c <= 'z'; c++)
  1193. X     re_syntax_table[c] = Sword;
  1194. X
  1195. X   for (c = 'A'; c <= 'Z'; c++)
  1196. X     re_syntax_table[c] = Sword;
  1197. X
  1198. X   for (c = '0'; c <= '9'; c++)
  1199. X     re_syntax_table[c] = Sword;
  1200. X
  1201. X   done = 1;
  1202. X}
  1203. X
  1204. X#endif /* SYNTAX_TABLE */
  1205. X#endif /* not emacs */
  1206. X
  1207. X#include "regex.h"
  1208. X
  1209. X/* Number of failure points to allocate space for initially,
  1210. X when matching.  If this number is exceeded, more space is allocated,
  1211. X so it is not a hard limit.  */
  1212. X
  1213. X#ifndef NFAILURES
  1214. X#define NFAILURES 80
  1215. X#endif /* NFAILURES */
  1216. X
  1217. X/* width of a byte in bits */
  1218. X
  1219. X#define BYTEWIDTH 8
  1220. X
  1221. X#ifndef SIGN_EXTEND_CHAR
  1222. X#define SIGN_EXTEND_CHAR(x) (x)
  1223. X#endif
  1224. X
  1225. Xstatic int obscure_syntax = 0;
  1226. X
  1227. X/* Specify the precise syntax of regexp for compilation.
  1228. X   This provides for compatibility for various utilities
  1229. X   which historically have different, incompatible syntaxes.
  1230. X
  1231. X   The argument SYNTAX is a bit-mask containing the two bits
  1232. X   RE_NO_BK_PARENS and RE_NO_BK_VBAR.  */
  1233. X
  1234. Xint
  1235. Xre_set_syntax (syntax)
  1236. X{
  1237. X  int ret;
  1238. X
  1239. X  ret = obscure_syntax;
  1240. X  obscure_syntax = syntax;
  1241. X  return ret;
  1242. X}
  1243. X
  1244. X/* re_compile_pattern takes a regular-expression string
  1245. X   and converts it into a buffer full of byte commands for matching.
  1246. X
  1247. X  PATTERN   is the address of the pattern string
  1248. X  SIZE      is the length of it.
  1249. X  BUFP        is a  struct re_pattern_buffer *  which points to the info
  1250. X        on where to store the byte commands.
  1251. X        This structure contains a  char *  which points to the
  1252. X        actual space, which should have been obtained with malloc.
  1253. X        re_compile_pattern may use  realloc  to grow the buffer space.
  1254. X
  1255. X  The number of bytes of commands can be found out by looking in
  1256. X  the  struct re_pattern_buffer  that bufp pointed to,
  1257. X  after re_compile_pattern returns.
  1258. X*/
  1259. X
  1260. X#define PATPUSH(ch) (*b++ = (char) (ch))
  1261. X
  1262. X#define PATFETCH(c) \
  1263. X {if (p == pend) goto end_of_pattern; \
  1264. X  c = * (unsigned char *) p++; \
  1265. X  if (translate) c = translate[c]; }
  1266. X
  1267. X#define PATFETCH_RAW(c) \
  1268. X {if (p == pend) goto end_of_pattern; \
  1269. X  c = * (unsigned char *) p++; }
  1270. X
  1271. X#define PATUNFETCH p--
  1272. X
  1273. X#define EXTEND_BUFFER \
  1274. X  { char *old_buffer = bufp->buffer; \
  1275. X    if (bufp->allocated == (1<<16)) goto too_big; \
  1276. X    bufp->allocated *= 2; \
  1277. X    if (bufp->allocated > (1<<16)) bufp->allocated = (1<<16); \
  1278. X    if (!(bufp->buffer = (char *) realloc (bufp->buffer, bufp->allocated))) \
  1279. X      goto memory_exhausted; \
  1280. X    c = bufp->buffer - old_buffer; \
  1281. X    b += c; \
  1282. X    if (fixup_jump) \
  1283. X      fixup_jump += c; \
  1284. X    if (laststart) \
  1285. X      laststart += c; \
  1286. X    begalt += c; \
  1287. X    if (pending_exact) \
  1288. X      pending_exact += c; \
  1289. X  }
  1290. X
  1291. Xstatic int store_jump (), insert_jump ();
  1292. X
  1293. Xchar *
  1294. Xre_compile_pattern (pattern, size, bufp)
  1295. X     char *pattern;
  1296. X     int size;
  1297. X     struct re_pattern_buffer *bufp;
  1298. X{
  1299. X  register char *b = bufp->buffer;
  1300. X  register char *p = pattern;
  1301. X  char *pend = pattern + size;
  1302. X  register unsigned c, c1;
  1303. X  char *p1;
  1304. X  unsigned char *translate = (unsigned char *) bufp->translate;
  1305. X
  1306. X  /* address of the count-byte of the most recently inserted "exactn" command.
  1307. X    This makes it possible to tell whether a new exact-match character
  1308. X    can be added to that command or requires a new "exactn" command. */
  1309. X     
  1310. X  char *pending_exact = 0;
  1311. X
  1312. X  /* address of the place where a forward-jump should go
  1313. X    to the end of the containing expression.
  1314. X    Each alternative of an "or", except the last, ends with a forward-jump
  1315. X    of this sort. */
  1316. X
  1317. X  char *fixup_jump = 0;
  1318. X
  1319. X  /* address of start of the most recently finished expression.
  1320. X    This tells postfix * where to find the start of its operand. */
  1321. X
  1322. X  char *laststart = 0;
  1323. X
  1324. X  /* In processing a repeat, 1 means zero matches is allowed */
  1325. X
  1326. X  char zero_times_ok;
  1327. X
  1328. X  /* In processing a repeat, 1 means many matches is allowed */
  1329. X
  1330. X  char many_times_ok;
  1331. X
  1332. X  /* address of beginning of regexp, or inside of last \( */
  1333. X
  1334. X  char *begalt = b;
  1335. X
  1336. X  /* Stack of information saved by \( and restored by \).
  1337. X     Four stack elements are pushed by each \(:
  1338. X       First, the value of b.
  1339. X       Second, the value of fixup_jump.
  1340. X       Third, the value of regnum.
  1341. X       Fourth, the value of begalt.  */
  1342. X
  1343. X  int stackb[40];
  1344. X  int *stackp = stackb;
  1345. X  int *stacke = stackb + 40;
  1346. X  int *stackt;
  1347. X
  1348. X  /* Counts \('s as they are encountered.  Remembered for the matching \),
  1349. X     where it becomes the "register number" to put in the stop_memory command */
  1350. X
  1351. X  int regnum = 1;
  1352. X
  1353. X  bufp->fastmap_accurate = 0;
  1354. X
  1355. X#ifndef emacs
  1356. X#ifndef SYNTAX_TABLE
  1357. X  /*
  1358. X   * Initialize the syntax table.
  1359. X   */
  1360. X   init_syntax_once();
  1361. X#endif
  1362. X#endif
  1363. X
  1364. X  if (bufp->allocated == 0)
  1365. X    {
  1366. X      bufp->allocated = 28;
  1367. X      if (bufp->buffer)
  1368. X    /* EXTEND_BUFFER loses when bufp->allocated is 0 */
  1369. X    bufp->buffer = (char *) realloc (bufp->buffer, 28);
  1370. X      else
  1371. X    /* Caller did not allocate a buffer.  Do it for him */
  1372. X    bufp->buffer = (char *) malloc (28);
  1373. X      if (!bufp->buffer) goto memory_exhausted;
  1374. X      begalt = b = bufp->buffer;
  1375. X    }
  1376. X
  1377. X  while (p != pend)
  1378. X    {
  1379. X      if (b - bufp->buffer > bufp->allocated - 10)
  1380. X    /* Note that EXTEND_BUFFER clobbers c */
  1381. X    EXTEND_BUFFER;
  1382. X
  1383. X      PATFETCH (c);
  1384. X
  1385. X      switch (c)
  1386. X    {
  1387. X    case '$':
  1388. X      if (obscure_syntax & RE_TIGHT_VBAR)
  1389. X        {
  1390. X          if (! (obscure_syntax & RE_CONTEXT_INDEP_OPS) && p != pend)
  1391. X        goto normal_char;
  1392. X          /* Make operand of last vbar end before this `$'.  */
  1393. X          if (fixup_jump)
  1394. X        store_jump (fixup_jump, jump, b);
  1395. X          fixup_jump = 0;
  1396. X          PATPUSH (endline);
  1397. X          break;
  1398. X        }
  1399. X
  1400. X      /* $ means succeed if at end of line, but only in special contexts.
  1401. X        If randomly in the middle of a pattern, it is a normal character. */
  1402. X      if (p == pend || *p == '\n'
  1403. X          || (obscure_syntax & RE_CONTEXT_INDEP_OPS)
  1404. X          || (obscure_syntax & RE_NO_BK_PARENS
  1405. X          ? *p == ')'
  1406. X          : *p == '\\' && p[1] == ')')
  1407. X          || (obscure_syntax & RE_NO_BK_VBAR
  1408. X          ? *p == '|'
  1409. X          : *p == '\\' && p[1] == '|'))
  1410. X        {
  1411. X          PATPUSH (endline);
  1412. X          break;
  1413. X        }
  1414. X      goto normal_char;
  1415. X
  1416. X    case '^':
  1417. X      /* ^ means succeed if at beg of line, but only if no preceding pattern. */
  1418. X
  1419. X      if (laststart && p[-2] != '\n'
  1420. X          && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
  1421. X        goto normal_char;
  1422. X      if (obscure_syntax & RE_TIGHT_VBAR)
  1423. X        {
  1424. X          if (p != pattern + 1
  1425. X          && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
  1426. X        goto normal_char;
  1427. X          PATPUSH (begline);
  1428. X          begalt = b;
  1429. X        }
  1430. X      else
  1431. X        PATPUSH (begline);
  1432. X      break;
  1433. X
  1434. X    case '+':
  1435. X    case '?':
  1436. X      if (obscure_syntax & RE_BK_PLUS_QM)
  1437. X        goto normal_char;
  1438. X    handle_plus:
  1439. X    case '*':
  1440. X      /* If there is no previous pattern, char not special. */
  1441. X      if (!laststart && ! (obscure_syntax & RE_CONTEXT_INDEP_OPS))
  1442. X        goto normal_char;
  1443. X      /* If there is a sequence of repetition chars,
  1444. X         collapse it down to equivalent to just one.  */
  1445. X      zero_times_ok = 0;
  1446. X      many_times_ok = 0;
  1447. X      while (1)
  1448. X        {
  1449. X          zero_times_ok |= c != '+';
  1450. X          many_times_ok |= c != '?';
  1451. X          if (p == pend)
  1452. X        break;
  1453. X          PATFETCH (c);
  1454. X          if (c == '*')
  1455. X        ;
  1456. X          else if (!(obscure_syntax & RE_BK_PLUS_QM)
  1457. X               && (c == '+' || c == '?'))
  1458. X        ;
  1459. X          else if ((obscure_syntax & RE_BK_PLUS_QM)
  1460. X               && c == '\\')
  1461. X        {
  1462. X          int c1;
  1463. X          PATFETCH (c1);
  1464. X          if (!(c1 == '+' || c1 == '?'))
  1465. X            {
  1466. X              PATUNFETCH;
  1467. X              PATUNFETCH;
  1468. X              break;
  1469. X            }
  1470. X          c = c1;
  1471. X        }
  1472. X          else
  1473. X        {
  1474. X          PATUNFETCH;
  1475. X          break;
  1476. X        }
  1477. X        }
  1478. X
  1479. X      /* Star, etc. applied to an empty pattern is equivalent
  1480. X         to an empty pattern.  */
  1481. X      if (!laststart)
  1482. X        break;
  1483. X
  1484. X      /* Now we know whether 0 matches is allowed,
  1485. X         and whether 2 or more matches is allowed.  */
  1486. X      if (many_times_ok)
  1487. X        {
  1488. X          /* If more than one repetition is allowed,
  1489. X         put in a backward jump at the end.  */
  1490. X          store_jump (b, maybe_finalize_jump, laststart - 3);
  1491. X          b += 3;
  1492. X        }
  1493. X      insert_jump (on_failure_jump, laststart, b + 3, b);
  1494. X      pending_exact = 0;
  1495. X      b += 3;
  1496. X      if (!zero_times_ok)
  1497. X        {
  1498. X          /* At least one repetition required: insert before the loop
  1499. X         a skip over the initial on-failure-jump instruction */
  1500. X          insert_jump (dummy_failure_jump, laststart, laststart + 6, b);
  1501. X          b += 3;
  1502. X        }
  1503. X      break;
  1504. X
  1505. X    case '.':
  1506. X      laststart = b;
  1507. X      PATPUSH (anychar);
  1508. X      break;
  1509. X
  1510. X    case '[':
  1511. X      while (b - bufp->buffer
  1512. X         > bufp->allocated - 3 - (1 << BYTEWIDTH) / BYTEWIDTH)
  1513. X        /* Note that EXTEND_BUFFER clobbers c */
  1514. X        EXTEND_BUFFER;
  1515. X
  1516. X      laststart = b;
  1517. X      if (*p == '^')
  1518. X        PATPUSH (charset_not), p++;
  1519. X      else
  1520. X        PATPUSH (charset);
  1521. X      p1 = p;
  1522. X
  1523. X      PATPUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
  1524. X      /* Clear the whole map */
  1525. X      bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
  1526. X      /* Read in characters and ranges, setting map bits */
  1527. X      while (1)
  1528. X        {
  1529. X          PATFETCH (c);
  1530. X          if (c == ']' && p != p1 + 1) break;
  1531. X          if (*p == '-' && p[1] != ']')
  1532. X        {
  1533. X          PATFETCH (c1);
  1534. X          PATFETCH (c1);
  1535. X          while (c <= c1)
  1536. X            b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH), c++;
  1537. X        }
  1538. X          else
  1539. X        {
  1540. X          b[c / BYTEWIDTH] |= 1 << (c % BYTEWIDTH);
  1541. X        }
  1542. X        }
  1543. X      /* Discard any bitmap bytes that are all 0 at the end of the map.
  1544. X         Decrement the map-length byte too. */
  1545. X      while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
  1546. X        b[-1]--;
  1547. X      b += b[-1];
  1548. X      break;
  1549. X
  1550. X    case '(':
  1551. X      if (! (obscure_syntax & RE_NO_BK_PARENS))
  1552. X        goto normal_char;
  1553. X      else
  1554. X        goto handle_open;
  1555. X
  1556. X    case ')':
  1557. X      if (! (obscure_syntax & RE_NO_BK_PARENS))
  1558. X        goto normal_char;
  1559. X      else
  1560. X        goto handle_close;
  1561. X
  1562. X    case '\n':
  1563. X      if (! (obscure_syntax & RE_NEWLINE_OR))
  1564. X        goto normal_char;
  1565. X      else
  1566. X        goto handle_bar;
  1567. X
  1568. X    case '|':
  1569. X      if (! (obscure_syntax & RE_NO_BK_VBAR))
  1570. X        goto normal_char;
  1571. X      else
  1572. X        goto handle_bar;
  1573. X
  1574. X        case '\\':
  1575. X      if (p == pend) goto invalid_pattern;
  1576. X      PATFETCH_RAW (c);
  1577. X      switch (c)
  1578. X        {
  1579. X        case '(':
  1580. X          if (obscure_syntax & RE_NO_BK_PARENS)
  1581. X        goto normal_backsl;
  1582. X        handle_open:
  1583. X          if (stackp == stacke) goto nesting_too_deep;
  1584. X          if (regnum < RE_NREGS)
  1585. X            {
  1586. X          PATPUSH (start_memory);
  1587. X          PATPUSH (regnum);
  1588. X            }
  1589. X          *stackp++ = b - bufp->buffer;
  1590. X          *stackp++ = fixup_jump ? fixup_jump - bufp->buffer + 1 : 0;
  1591. X          *stackp++ = regnum++;
  1592. X          *stackp++ = begalt - bufp->buffer;
  1593. X          fixup_jump = 0;
  1594. X          laststart = 0;
  1595. X          begalt = b;
  1596. X          break;
  1597. X
  1598. X        case ')':
  1599. X          if (obscure_syntax & RE_NO_BK_PARENS)
  1600. X        goto normal_backsl;
  1601. X        handle_close:
  1602. X          if (stackp == stackb) goto unmatched_close;
  1603. X          begalt = *--stackp + bufp->buffer;
  1604. X          if (fixup_jump)
  1605. X        store_jump (fixup_jump, jump, b);
  1606. X          if (stackp[-1] < RE_NREGS)
  1607. X        {
  1608. X          PATPUSH (stop_memory);
  1609. X          PATPUSH (stackp[-1]);
  1610. X        }
  1611. X          stackp -= 2;
  1612. X          fixup_jump = 0;
  1613. X          if (*stackp)
  1614. X        fixup_jump = *stackp + bufp->buffer - 1;
  1615. X          laststart = *--stackp + bufp->buffer;
  1616. X          break;
  1617. X
  1618. X        case '|':
  1619. X          if (obscure_syntax & RE_NO_BK_VBAR)
  1620. X        goto normal_backsl;
  1621. X        handle_bar:
  1622. X          insert_jump (on_failure_jump, begalt, b + 6, b);
  1623. X          pending_exact = 0;
  1624. X          b += 3;
  1625. X          if (fixup_jump)
  1626. X        store_jump (fixup_jump, jump, b);
  1627. X          fixup_jump = b;
  1628. X          b += 3;
  1629. X          laststart = 0;
  1630. X          begalt = b;
  1631. X          break;
  1632. X
  1633. X#ifdef emacs
  1634. X        case '=':
  1635. X          PATPUSH (at_dot);
  1636. X          break;
  1637. X
  1638. X        case 's':    
  1639. X          laststart = b;
  1640. X          PATPUSH (syntaxspec);
  1641. X          PATFETCH (c);
  1642. X          PATPUSH (syntax_spec_code[c]);
  1643. X          break;
  1644. X
  1645. X        case 'S':
  1646. X          laststart = b;
  1647. X          PATPUSH (notsyntaxspec);
  1648. X          PATFETCH (c);
  1649. X          PATPUSH (syntax_spec_code[c]);
  1650. X          break;
  1651. X#endif /* emacs */
  1652. X
  1653. X        case 'w':
  1654. X          laststart = b;
  1655. X          PATPUSH (wordchar);
  1656. X          break;
  1657. X
  1658. X        case 'W':
  1659. X          laststart = b;
  1660. X          PATPUSH (notwordchar);
  1661. X          break;
  1662. X
  1663. X        case '<':
  1664. X          PATPUSH (wordbeg);
  1665. X          break;
  1666. X
  1667. X        case '>':
  1668. X          PATPUSH (wordend);
  1669. X          break;
  1670. X
  1671. X        case 'b':
  1672. X          PATPUSH (wordbound);
  1673. X          break;
  1674. X
  1675. X        case 'B':
  1676. X          PATPUSH (notwordbound);
  1677. X          break;
  1678. X
  1679. X        case '`':
  1680. X          PATPUSH (begbuf);
  1681. X          break;
  1682. X
  1683. X        case '\'':
  1684. X          PATPUSH (endbuf);
  1685. X          break;
  1686. X
  1687. X        case '1':
  1688. X        case '2':
  1689. X        case '3':
  1690. X        case '4':
  1691. X        case '5':
  1692. X        case '6':
  1693. X        case '7':
  1694. X        case '8':
  1695. X        case '9':
  1696. X          c1 = c - '0';
  1697. X          if (c1 >= regnum)
  1698. X        goto normal_char;
  1699. X          for (stackt = stackp - 2;  stackt > stackb;  stackt -= 4)
  1700. X         if (*stackt == c1)
  1701. X          goto normal_char;
  1702. X          laststart = b;
  1703. X          PATPUSH (duplicate);
  1704. X          PATPUSH (c1);
  1705. X          break;
  1706. X
  1707. X        case '+':
  1708. X        case '?':
  1709. X          if (obscure_syntax & RE_BK_PLUS_QM)
  1710. X        goto handle_plus;
  1711. X
  1712. X        default:
  1713. X        normal_backsl:
  1714. X          /* You might think it would be useful for \ to mean
  1715. X         not to translate; but if we don't translate it
  1716. X         it will never match anything.  */
  1717. X          if (translate) c = translate[c];
  1718. X          goto normal_char;
  1719. X        }
  1720. X      break;
  1721. X
  1722. X    default:
  1723. X    normal_char:
  1724. X      if (!pending_exact || pending_exact + *pending_exact + 1 != b
  1725. X          || *pending_exact == 0177 || *p == '*' || *p == '^'
  1726. X          || ((obscure_syntax & RE_BK_PLUS_QM)
  1727. X          ? *p == '\\' && (p[1] == '+' || p[1] == '?')
  1728. X          : (*p == '+' || *p == '?')))
  1729. X        {
  1730. X          laststart = b;
  1731. X          PATPUSH (exactn);
  1732. X          pending_exact = b;
  1733. X          PATPUSH (0);
  1734. X        }
  1735. X      PATPUSH (c);
  1736. X      (*pending_exact)++;
  1737. X    }
  1738. X    }
  1739. X
  1740. X  if (fixup_jump)
  1741. X    store_jump (fixup_jump, jump, b);
  1742. X
  1743. X  if (stackp != stackb) goto unmatched_open;
  1744. X
  1745. X  bufp->used = b - bufp->buffer;
  1746. X  return 0;
  1747. X
  1748. X invalid_pattern:
  1749. X  return "Invalid regular expression";
  1750. X
  1751. X unmatched_open:
  1752. X  return "Unmatched \\(";
  1753. X
  1754. X unmatched_close:
  1755. X  return "Unmatched \\)";
  1756. X
  1757. X end_of_pattern:
  1758. X  return "Premature end of regular expression";
  1759. X
  1760. X nesting_too_deep:
  1761. X  return "Nesting too deep";
  1762. X
  1763. X too_big:
  1764. X  return "Regular expression too big";
  1765. X
  1766. X memory_exhausted:
  1767. X  return "Memory exhausted";
  1768. X}
  1769. X
  1770. X/* Store where `from' points a jump operation to jump to where `to' points.
  1771. X  `opcode' is the opcode to store. */
  1772. X
  1773. Xstatic int
  1774. Xstore_jump (from, opcode, to)
  1775. X     char *from, *to;
  1776. X     char opcode;
  1777. X{
  1778. X  from[0] = opcode;
  1779. X  from[1] = (to - (from + 3)) & 0377;
  1780. X  from[2] = (to - (from + 3)) >> 8;
  1781. X  return(0);
  1782. X}
  1783. X
  1784. X/* Open up space at char FROM, and insert there a jump to TO.
  1785. X   CURRENT_END gives te end of the storage no in use,
  1786. X   so we know how much data to copy up.
  1787. X   OP is the opcode of the jump to insert.
  1788. X
  1789. X   If you call this function, you must zero out pending_exact.  */
  1790. X
  1791. Xstatic int
  1792. Xinsert_jump (op, from, to, current_end)
  1793. X     char op;
  1794. X     char *from, *to, *current_end;
  1795. X{
  1796. X  register char *pto = current_end + 3;
  1797. X  register char *pfrom = current_end;
  1798. X  while (pfrom != from)
  1799. X    *--pto = *--pfrom;
  1800. X  store_jump (from, op, to);
  1801. X  return(0);
  1802. X}
  1803. X
  1804. X/* Given a pattern, compute a fastmap from it.
  1805. X The fastmap records which of the (1 << BYTEWIDTH) possible characters
  1806. X can start a string that matches the pattern.
  1807. X This fastmap is used by re_search to skip quickly over totally implausible text.
  1808. X
  1809. X The caller must supply the address of a (1 << BYTEWIDTH)-byte data area
  1810. X as bufp->fastmap.
  1811. X The other components of bufp describe the pattern to be used.  */
  1812. X
  1813. Xvoid
  1814. Xre_compile_fastmap (bufp)
  1815. X     struct re_pattern_buffer *bufp;
  1816. X{
  1817. X  unsigned char *pattern = (unsigned char *) bufp->buffer;
  1818. X  int size = bufp->used;
  1819. X  register char *fastmap = bufp->fastmap;
  1820. X  register unsigned char *p = pattern;
  1821. X  register unsigned char *pend = pattern + size;
  1822. X  register int j;
  1823. X  unsigned char *translate = (unsigned char *) bufp->translate;
  1824. X
  1825. X  unsigned char *stackb[NFAILURES];
  1826. X  unsigned char **stackp = stackb;
  1827. X
  1828. X  bzero (fastmap, (1 << BYTEWIDTH));
  1829. X  bufp->fastmap_accurate = 1;
  1830. X  bufp->can_be_null = 0;
  1831. X      
  1832. X  while (p)
  1833. X    {
  1834. X      if (p == pend)
  1835. X    {
  1836. X      bufp->can_be_null = 1;
  1837. X      break;
  1838. X    }
  1839. X#ifdef SWITCH_ENUM_BUG
  1840. X      switch ((int) ((enum regexpcode) *p++))
  1841. X#else
  1842. X      switch ((enum regexpcode) *p++)
  1843. X#endif
  1844. X    {
  1845. X    case exactn:
  1846. X      if (translate)
  1847. X        fastmap[translate[p[1]]] = 1;
  1848. X      else
  1849. X        fastmap[p[1]] = 1;
  1850. X      break;
  1851. X
  1852. X        case begline:
  1853. X        case before_dot:
  1854. X    case at_dot:
  1855. X    case after_dot:
  1856. X    case begbuf:
  1857. X    case endbuf:
  1858. X    case wordbound:
  1859. X    case notwordbound:
  1860. X    case wordbeg:
  1861. X    case wordend:
  1862. X      continue;
  1863. X
  1864. X    case endline:
  1865. X      if (translate)
  1866. X        fastmap[translate['\n']] = 1;
  1867. X      else
  1868. X        fastmap['\n'] = 1;
  1869. X      if (bufp->can_be_null != 1)
  1870. X        bufp->can_be_null = 2;
  1871. X      break;
  1872. X
  1873. X    case finalize_jump:
  1874. X    case maybe_finalize_jump:
  1875. X    case jump:
  1876. X    case dummy_failure_jump:
  1877. X      bufp->can_be_null = 1;
  1878. X      j = *p++ & 0377;
  1879. X      j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
  1880. X      p += j + 1;        /* The 1 compensates for missing ++ above */
  1881. X      if (j > 0)
  1882. X        continue;
  1883. X      /* Jump backward reached implies we just went through
  1884. X         the body of a loop and matched nothing.
  1885. X         Opcode jumped to should be an on_failure_jump.
  1886. X         Just treat it like an ordinary jump.
  1887. X         For a * loop, it has pushed its failure point already;
  1888. X         if so, discard that as redundant.  */
  1889. X      if ((enum regexpcode) *p != on_failure_jump)
  1890. X        continue;
  1891. X      p++;
  1892. X      j = *p++ & 0377;
  1893. X      j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
  1894. X      p += j + 1;        /* The 1 compensates for missing ++ above */
  1895. X      if (stackp != stackb && *stackp == p)
  1896. X        stackp--;
  1897. X      continue;
  1898. X      
  1899. X    case on_failure_jump:
  1900. X      j = *p++ & 0377;
  1901. X      j += SIGN_EXTEND_CHAR (*(char *)p) << 8;
  1902. X      p++;
  1903. X      *++stackp = p + j;
  1904. X      continue;
  1905. X
  1906. X    case start_memory:
  1907. X    case stop_memory:
  1908. X      p++;
  1909. X      continue;
  1910. X
  1911. X    case duplicate:
  1912. X      bufp->can_be_null = 1;
  1913. X      fastmap['\n'] = 1;
  1914. X    case anychar:
  1915. X      for (j = 0; j < (1 << BYTEWIDTH); j++)
  1916. X        if (j != '\n')
  1917. X          fastmap[j] = 1;
  1918. X      if (bufp->can_be_null)
  1919. X        return;
  1920. X      /* Don't return; check the alternative paths
  1921. X         so we can set can_be_null if appropriate.  */
  1922. X      break;
  1923. X
  1924. X    case wordchar:
  1925. X      for (j = 0; j < (1 << BYTEWIDTH); j++)
  1926. X        if (SYNTAX (j) == Sword)
  1927. X          fastmap[j] = 1;
  1928. X      break;
  1929. X
  1930. X    case notwordchar:
  1931. X      for (j = 0; j < (1 << BYTEWIDTH); j++)
  1932. X        if (SYNTAX (j) != Sword)
  1933. X          fastmap[j] = 1;
  1934. X      break;
  1935. X
  1936. X#ifdef emacs
  1937. X    case syntaxspec:
  1938. X      k = *p++;
  1939. X      for (j = 0; j < (1 << BYTEWIDTH); j++)
  1940. X        if (SYNTAX (j) == (enum syntaxcode) k)
  1941. X          fastmap[j] = 1;
  1942. X      break;
  1943. X
  1944. X    case notsyntaxspec:
  1945. X      k = *p++;
  1946. X      for (j = 0; j < (1 << BYTEWIDTH); j++)
  1947. X        if (SYNTAX (j) != (enum syntaxcode) k)
  1948. X          fastmap[j] = 1;
  1949. X      break;
  1950. X#endif /* emacs */
  1951. X
  1952. X    case charset:
  1953. X      for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
  1954. X        if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
  1955. X          {
  1956. X        if (translate)
  1957. X          fastmap[translate[j]] = 1;
  1958. X        else
  1959. X          fastmap[j] = 1;
  1960. X          }
  1961. X      break;
  1962. X
  1963. X    case charset_not:
  1964. X      /* Chars beyond end of map must be allowed */
  1965. X      for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
  1966. X        if (translate)
  1967. X          fastmap[translate[j]] = 1;
  1968. X        else
  1969. X          fastmap[j] = 1;
  1970. X
  1971. X      for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
  1972. X        if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
  1973. X          {
  1974. X        if (translate)
  1975. X          fastmap[translate[j]] = 1;
  1976. X        else
  1977. X          fastmap[j] = 1;
  1978. X          }
  1979. X      break;
  1980. X    }
  1981. X
  1982. X      /* Get here means we have successfully found the possible starting characters
  1983. X     of one path of the pattern.  We need not follow this path any farther.
  1984. X     Instead, look at the next alternative remembered in the stack. */
  1985. X      if (stackp != stackb)
  1986. X    p = *stackp--;
  1987. X      else
  1988. X    break;
  1989. X    }
  1990. X}
  1991. X
  1992. X/* Like re_search_2, below, but only one string is specified. */
  1993. X
  1994. Xint
  1995. Xre_search (pbufp, string, size, startpos, range, regs)
  1996. X     struct re_pattern_buffer *pbufp;
  1997. X     char *string;
  1998. X     int size, startpos, range;
  1999. X     struct re_registers *regs;
  2000. X{
  2001. X  return re_search_2 (pbufp, 0, 0, string, size, startpos, range, regs, size);
  2002. X}
  2003. X
  2004. X/* Like re_match_2 but tries first a match starting at index STARTPOS,
  2005. X   then at STARTPOS + 1, and so on.
  2006. X   RANGE is the number of places to try before giving up.
  2007. X   If RANGE is negative, the starting positions tried are
  2008. X    STARTPOS, STARTPOS - 1, etc.
  2009. X   It is up to the caller to make sure that range is not so large
  2010. X   as to take the starting position outside of the input strings.
  2011. X
  2012. XThe value returned is the position at which the match was found,
  2013. X or -1 if no match was found,
  2014. X or -2 if error (such as failure stack overflow).  */
  2015. X
  2016. Xint
  2017. Xre_search_2 (pbufp, string1, size1, string2, size2, startpos, range, regs, mstop)
  2018. X     struct re_pattern_buffer *pbufp;
  2019. X     char *string1, *string2;
  2020. X     int size1, size2;
  2021. X     int startpos;
  2022. X     register int range;
  2023. X     struct re_registers *regs;
  2024. X     int mstop;
  2025. X{
  2026. X  register char *fastmap = pbufp->fastmap;
  2027. X  register unsigned char *translate = (unsigned char *) pbufp->translate;
  2028. X  int total = size1 + size2;
  2029. X  int val;
  2030. X
  2031. X  /* Update the fastmap now if not correct already */
  2032. X  if (fastmap && !pbufp->fastmap_accurate)
  2033. X    re_compile_fastmap (pbufp);
  2034. X  
  2035. X  /* Don't waste time in a long search for a pattern
  2036. X     that says it is anchored.  */
  2037. X  if (pbufp->used > 0 && (enum regexpcode) pbufp->buffer[0] == begbuf
  2038. X      && range > 0)
  2039. X    {
  2040. X      if (startpos > 0)
  2041. X    return -1;
  2042. X      else
  2043. X    range = 1;
  2044. X    }
  2045. X
  2046. X  while (1)
  2047. X    {
  2048. X      /* If a fastmap is supplied, skip quickly over characters
  2049. X     that cannot possibly be the start of a match.
  2050. X     Note, however, that if the pattern can possibly match
  2051. X     the null string, we must test it at each starting point
  2052. X     so that we take the first null string we get.  */
  2053. X
  2054. X      if (fastmap && startpos < total && pbufp->can_be_null != 1)
  2055. X    {
  2056. X      if (range > 0)
  2057. X        {
  2058. X          register int lim = 0;
  2059. X          register unsigned char *p;
  2060. X          int irange = range;
  2061. X          if (startpos < size1 && startpos + range >= size1)
  2062. X        lim = range - (size1 - startpos);
  2063. X
  2064. X          p = ((unsigned char *)
  2065. X           &(startpos >= size1 ? string2 - size1 : string1)[startpos]);
  2066. X
  2067. X          if (translate)
  2068. X        {
  2069. X          while (range > lim && !fastmap[translate[*p++]])
  2070. X            range--;
  2071. X        }
  2072. X          else
  2073. X        {
  2074. X          while (range > lim && !fastmap[*p++])
  2075. X            range--;
  2076. X        }
  2077. X          startpos += irange - range;
  2078. X        }
  2079. X      else
  2080. X        {
  2081. X          register unsigned char c;
  2082. X          if (startpos >= size1)
  2083. X        c = string2[startpos - size1];
  2084. X          else
  2085. X        c = string1[startpos];
  2086. X          c &= 0xff;
  2087. X          if (translate ? !fastmap[translate[c]] : !fastmap[c])
  2088. X        goto advance;
  2089. X        }
  2090. X    }
  2091. X
  2092. X      if (range >= 0 && startpos == total
  2093. X      && fastmap && pbufp->can_be_null == 0)
  2094. X    return -1;
  2095. X
  2096. X      val = re_match_2 (pbufp, string1, size1, string2, size2, startpos, regs, mstop);
  2097. X      if (0 <= val)
  2098. X    {
  2099. X      if (val == -2)
  2100. X        return -2;
  2101. X      return startpos;
  2102. X    }
  2103. X
  2104. X#ifdef C_ALLOCA
  2105. X      alloca (0);
  2106. X#endif /* C_ALLOCA */
  2107. X
  2108. X    advance:
  2109. X      if (!range) break;
  2110. X      if (range > 0) range--, startpos++; else range++, startpos--;
  2111. X    }
  2112. X  return -1;
  2113. X}
  2114. X
  2115. X#ifndef emacs   /* emacs never uses this */
  2116. Xint
  2117. Xre_match (pbufp, string, size, pos, regs)
  2118. X     struct re_pattern_buffer *pbufp;
  2119. X     char *string;
  2120. X     int size, pos;
  2121. X     struct re_registers *regs;
  2122. X{
  2123. X  return re_match_2 (pbufp, 0, 0, string, size, pos, regs, size);
  2124. X}
  2125. X#endif /* emacs */
  2126. X
  2127. X/* Maximum size of failure stack.  Beyond this, overflow is an error.  */
  2128. X
  2129. Xint re_max_failures = 2000;
  2130. X
  2131. Xstatic int bcmp_translate();
  2132. X/* Match the pattern described by PBUFP
  2133. X   against data which is the virtual concatenation of STRING1 and STRING2.
  2134. X   SIZE1 and SIZE2 are the sizes of the two data strings.
  2135. X   Start the match at position POS.
  2136. X   Do not consider matching past the position MSTOP.
  2137. X
  2138. X   If pbufp->fastmap is nonzero, then it had better be up to date.
  2139. X
  2140. X   The reason that the data to match are specified as two components
  2141. X   which are to be regarded as concatenated
  2142. X   is so this function can be used directly on the contents of an Emacs buffer.
  2143. X
  2144. X   -1 is returned if there is no match.  -2 is returned if there is
  2145. X   an error (such as match stack overflow).  Otherwise the value is the length
  2146. X   of the substring which was matched.  */
  2147. X
  2148. Xint
  2149. Xre_match_2 (pbufp, string1, size1, string2, size2, pos, regs, mstop)
  2150. X     struct re_pattern_buffer *pbufp;
  2151. X     unsigned char *string1, *string2;
  2152. X     int size1, size2;
  2153. X     int pos;
  2154. X     struct re_registers *regs;
  2155. X     int mstop;
  2156. X{
  2157. X  register unsigned char *p = (unsigned char *) pbufp->buffer;
  2158. X  register unsigned char *pend = p + pbufp->used;
  2159. X  /* End of first string */
  2160. X  unsigned char *end1;
  2161. X  /* End of second string */
  2162. X  unsigned char *end2;
  2163. X  /* Pointer just past last char to consider matching */
  2164. X  unsigned char *end_match_1, *end_match_2;
  2165. X  register unsigned char *d, *dend;
  2166. X  register int mcnt;
  2167. X  unsigned char *translate = (unsigned char *) pbufp->translate;
  2168. X
  2169. X /* Failure point stack.  Each place that can handle a failure further down the line
  2170. X    pushes a failure point on this stack.  It consists of two char *'s.
  2171. X    The first one pushed is where to resume scanning the pattern;
  2172. X    the second pushed is where to resume scanning the strings.
  2173. X    If the latter is zero, the failure point is a "dummy".
  2174. X    If a failure happens and the innermost failure point is dormant,
  2175. X    it discards that failure point and tries the next one. */
  2176. X
  2177. X  unsigned char *initial_stack[2 * NFAILURES];
  2178. X  unsigned char **stackb = initial_stack;
  2179. X  unsigned char **stackp = stackb, **stacke = &stackb[2 * NFAILURES];
  2180. X
  2181. X  /* Information on the "contents" of registers.
  2182. X     These are pointers into the input strings; they record
  2183. X     just what was matched (on this attempt) by some part of the pattern.
  2184. X     The start_memory command stores the start of a register's contents
  2185. X     and the stop_memory command stores the end.
  2186. X
  2187. X     At that point, regstart[regnum] points to the first character in the register,
  2188. X     regend[regnum] points to the first character beyond the end of the register,
  2189. X     regstart_seg1[regnum] is true iff regstart[regnum] points into string1,
  2190. X     and regend_seg1[regnum] is true iff regend[regnum] points into string1.  */
  2191. X
  2192. X  unsigned char *regstart[RE_NREGS];
  2193. X  unsigned char *regend[RE_NREGS];
  2194. X  unsigned char regstart_seg1[RE_NREGS], regend_seg1[RE_NREGS];
  2195. X
  2196. X  /* Set up pointers to ends of strings.
  2197. X     Don't allow the second string to be empty unless both are empty.  */
  2198. X  if (!size2)
  2199. X    {
  2200. X      string2 = string1;
  2201. X      size2 = size1;
  2202. X      string1 = 0;
  2203. X      size1 = 0;
  2204. X    }
  2205. X  end1 = string1 + size1;
  2206. X  end2 = string2 + size2;
  2207. X
  2208. X  /* Compute where to stop matching, within the two strings */
  2209. X  if (mstop <= size1)
  2210. X    {
  2211. X      end_match_1 = string1 + mstop;
  2212. X      end_match_2 = string2;
  2213. X    }
  2214. X  else
  2215. X    {
  2216. X      end_match_1 = end1;
  2217. X      end_match_2 = string2 + mstop - size1;
  2218. X    }
  2219. X
  2220. X  /* Initialize \) text positions to -1
  2221. X     to mark ones that no \( or \) has been seen for.  */
  2222. X
  2223. X  for (mcnt = 0; mcnt < sizeof (regend) / sizeof (*regend); mcnt++)
  2224. X    regend[mcnt] = (unsigned char *) -1;
  2225. X
  2226. X  /* `p' scans through the pattern as `d' scans through the data.
  2227. X     `dend' is the end of the input string that `d' points within.
  2228. X     `d' is advanced into the following input string whenever necessary,
  2229. X     but this happens before fetching;
  2230. X     therefore, at the beginning of the loop,
  2231. X     `d' can be pointing at the end of a string,
  2232. X     but it cannot equal string2.  */
  2233. X
  2234. X  if (pos <= size1)
  2235. X    d = string1 + pos, dend = end_match_1;
  2236. X  else
  2237. X    d = string2 + pos - size1, dend = end_match_2;
  2238. X
  2239. X/* Write PREFETCH; just before fetching a character with *d.  */
  2240. X#define PREFETCH \
  2241. X while (d == dend)                            \
  2242. X  { if (dend == end_match_2) goto fail;  /* end of string2 => failure */   \
  2243. X    d = string2;  /* end of string1 => advance to string2. */       \
  2244. X    dend = end_match_2; }
  2245. X
  2246. X  /* This loop loops over pattern commands.
  2247. X     It exits by returning from the function if match is complete,
  2248. X     or it drops through if match fails at this starting point in the input data. */
  2249. X
  2250. X  while (1)
  2251. X    {
  2252. X      if (p == pend)
  2253. X    /* End of pattern means we have succeeded! */
  2254. X    {
  2255. X      /* If caller wants register contents data back, convert it to indices */
  2256. X      if (regs)
  2257. X        {
  2258. X           regs->start[0] = pos;
  2259. X           if (dend == end_match_1)
  2260. X         regs->end[0] = d - string1;
  2261. X           else
  2262. X         regs->end[0] = d - string2 + size1;
  2263. X           for (mcnt = 1; mcnt < RE_NREGS; mcnt++)
  2264. X        {
  2265. X          if (regend[mcnt] == (unsigned char *) -1)
  2266. X            {
  2267. X              regs->start[mcnt] = -1;
  2268. X              regs->end[mcnt] = -1;
  2269. X              continue;
  2270. X            }
  2271. X           if (regstart_seg1[mcnt])
  2272. X            regs->start[mcnt] = regstart[mcnt] - string1;
  2273. X          else
  2274. X            regs->start[mcnt] = regstart[mcnt] - string2 + size1;
  2275. X           if (regend_seg1[mcnt])
  2276. X            regs->end[mcnt] = regend[mcnt] - string1;
  2277. X          else
  2278. X            regs->end[mcnt] = regend[mcnt] - string2 + size1;
  2279. X        }
  2280. X        }
  2281. X       if (dend == end_match_1)
  2282. X        return (d - string1 - pos);
  2283. X      else
  2284. X        return d - string2 + size1 - pos;
  2285. X    }
  2286. X
  2287. X      /* Otherwise match next pattern command */
  2288. X#ifdef SWITCH_ENUM_BUG
  2289. X      switch ((int) ((enum regexpcode) *p++))
  2290. X#else
  2291. X      switch ((enum regexpcode) *p++)
  2292. X#endif
  2293. X    {
  2294. X
  2295. X    /* \( is represented by a start_memory, \) by a stop_memory.
  2296. X        Both of those commands contain a "register number" argument.
  2297. X        The text matched within the \( and \) is recorded under that number.
  2298. X        Then, \<digit> turns into a `duplicate' command which
  2299. X        is followed by the numeric value of <digit> as the register number. */
  2300. X
  2301. X    case start_memory:
  2302. X      regstart[*p] = d;
  2303. X       regstart_seg1[*p++] = (dend == end_match_1);
  2304. X      break;
  2305. X
  2306. X    case stop_memory:
  2307. X      regend[*p] = d;
  2308. X       regend_seg1[*p++] = (dend == end_match_1);
  2309. X      break;
  2310. X
  2311. X    case duplicate:
  2312. X      {
  2313. X        int regno = *p++;   /* Get which register to match against */
  2314. X        register unsigned char *d2, *dend2;
  2315. X
  2316. X        d2 = regstart[regno];
  2317. X         dend2 = ((regstart_seg1[regno] == regend_seg1[regno])
  2318. X             ? regend[regno] : end_match_1);
  2319. X        while (1)
  2320. X          {
  2321. X        /* Advance to next segment in register contents, if necessary */
  2322. X        while (d2 == dend2)
  2323. X          {
  2324. X            if (dend2 == end_match_2) break;
  2325. X            if (dend2 == regend[regno]) break;
  2326. X            d2 = string2, dend2 = regend[regno];  /* end of string1 => advance to string2. */
  2327. X          }
  2328. X        /* At end of register contents => success */
  2329. X        if (d2 == dend2) break;
  2330. X
  2331. X        /* Advance to next segment in data being matched, if necessary */
  2332. X        PREFETCH;
  2333. X
  2334. X        /* mcnt gets # consecutive chars to compare */
  2335. X        mcnt = dend - d;
  2336. X        if (mcnt > dend2 - d2)
  2337. X          mcnt = dend2 - d2;
  2338. X        /* Compare that many; failure if mismatch, else skip them. */
  2339. X        if (translate ? bcmp_translate (d, d2, mcnt, translate) : bcmp (d, d2, mcnt))
  2340. X          goto fail;
  2341. X        d += mcnt, d2 += mcnt;
  2342. X          }
  2343. X      }
  2344. X      break;
  2345. X
  2346. X    case anychar:
  2347. X      /* fetch a data character */
  2348. X      PREFETCH;
  2349. X      /* Match anything but a newline.  */
  2350. X      if ((translate ? translate[*d++] : *d++) == '\n')
  2351. X        goto fail;
  2352. X      break;
  2353. X
  2354. X    case charset:
  2355. X    case charset_not:
  2356. X      {
  2357. X        /* Nonzero for charset_not */
  2358. X        int not = 0;
  2359. X        register int c;
  2360. X        if (*(p - 1) == (unsigned char) charset_not)
  2361. X          not = 1;
  2362. X
  2363. X        /* fetch a data character */
  2364. X        PREFETCH;
  2365. X
  2366. X        if (translate)
  2367. X          c = translate [*d];
  2368. X        else
  2369. X          c = *d;
  2370. X
  2371. X        if (c < *p * BYTEWIDTH
  2372. X        && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
  2373. X          not = !not;
  2374. X
  2375. X        p += 1 + *p;
  2376. X
  2377. X        if (!not) goto fail;
  2378. X        d++;
  2379. X        break;
  2380. X      }
  2381. X
  2382. X    case begline:
  2383. X      if (d == string1 || d[-1] == '\n')
  2384. X        break;
  2385. X      goto fail;
  2386. X
  2387. X    case endline:
  2388. X      if (d == end2
  2389. X          || (d == end1 ? (size2 == 0 || *string2 == '\n') : *d == '\n'))
  2390. X        break;
  2391. X      goto fail;
  2392. X
  2393. X    /* "or" constructs ("|") are handled by starting each alternative
  2394. X        with an on_failure_jump that points to the start of the next alternative.
  2395. X        Each alternative except the last ends with a jump to the joining point.
  2396. X        (Actually, each jump except for the last one really jumps
  2397. X         to the following jump, because tensioning the jumps is a hassle.) */
  2398. X
  2399. X    /* The start of a stupid repeat has an on_failure_jump that points
  2400. X       past the end of the repeat text.
  2401. X       This makes a failure point so that, on failure to match a repetition,
  2402. X       matching restarts past as many repetitions have been found
  2403. X       with no way to fail and look for another one.  */
  2404. X
  2405. X    /* A smart repeat is similar but loops back to the on_failure_jump
  2406. X       so that each repetition makes another failure point. */
  2407. X
  2408. X    case on_failure_jump:
  2409. X      if (stackp == stacke)
  2410. X        {
  2411. X          unsigned char **stackx;
  2412. X          if (stacke - stackb > re_max_failures * 2)
  2413. X        return -2;
  2414. X          stackx = (unsigned char **) alloca (2 * (stacke - stackb)
  2415. X                     * sizeof (char *));
  2416. X          bcopy (stackb, stackx, (stacke - stackb) * sizeof (char *));
  2417. X          stackp = stackx + (stackp - stackb);
  2418. X          stacke = stackx + 2 * (stacke - stackb);
  2419. X          stackb = stackx;
  2420. X        }
  2421. X      mcnt = *p++ & 0377;
  2422. X      mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
  2423. X      p++;
  2424. X      *stackp++ = mcnt + p;
  2425. X      *stackp++ = d;
  2426. X      break;
  2427. X
  2428. X    /* The end of a smart repeat has an maybe_finalize_jump back.
  2429. X       Change it either to a finalize_jump or an ordinary jump. */
  2430. X
  2431. X    case maybe_finalize_jump:
  2432. X      mcnt = *p++ & 0377;
  2433. X      mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
  2434. X      p++;
  2435. X      {
  2436. X        register unsigned char *p2 = p;
  2437. X        /* Compare what follows with the begining of the repeat.
  2438. X           If we can establish that there is nothing that they would
  2439. X           both match, we can change to finalize_jump */
  2440. X        while (p2 != pend
  2441. X           && (*p2 == (unsigned char) stop_memory
  2442. X               || *p2 == (unsigned char) start_memory))
  2443. X          p2++;
  2444. X        if (p2 == pend)
  2445. X          p[-3] = (unsigned char) finalize_jump;
  2446. X        else if (*p2 == (unsigned char) exactn
  2447. X             || *p2 == (unsigned char) endline)
  2448. X          {
  2449. X        register int c = *p2 == (unsigned char) endline ? '\n' : p2[2];
  2450. X        register unsigned char *p1 = p + mcnt;
  2451. X        /* p1[0] ... p1[2] are an on_failure_jump.
  2452. X           Examine what follows that */
  2453. X        if (p1[3] == (unsigned char) exactn && p1[5] != c)
  2454. X          p[-3] = (unsigned char) finalize_jump;
  2455. X        else if (p1[3] == (unsigned char) charset
  2456. X             || p1[3] == (unsigned char) charset_not)
  2457. X          {
  2458. X            int not = p1[3] == (unsigned char) charset_not;
  2459. X            if (c < p1[4] * BYTEWIDTH
  2460. X            && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
  2461. X              not = !not;
  2462. X            /* not is 1 if c would match */
  2463. X            /* That means it is not safe to finalize */
  2464. X            if (!not)
  2465. X              p[-3] = (unsigned char) finalize_jump;
  2466. X          }
  2467. X          }
  2468. X      }
  2469. X      p -= 2;
  2470. X      if (p[-1] != (unsigned char) finalize_jump)
  2471. X        {
  2472. X          p[-1] = (unsigned char) jump;
  2473. X          goto nofinalize;
  2474. X        }
  2475. X
  2476. X    /* The end of a stupid repeat has a finalize-jump
  2477. X       back to the start, where another failure point will be made
  2478. X       which will point after all the repetitions found so far. */
  2479. X
  2480. X    case finalize_jump:
  2481. X      stackp -= 2;
  2482. X
  2483. X    case jump:
  2484. X    nofinalize:
  2485. X      mcnt = *p++ & 0377;
  2486. X      mcnt += SIGN_EXTEND_CHAR (*(char *)p) << 8;
  2487. X      p += mcnt + 1;    /* The 1 compensates for missing ++ above */
  2488. X      break;
  2489. X
  2490. X    case dummy_failure_jump:
  2491. X      if (stackp == stacke)
  2492. X        {
  2493. X          unsigned char **stackx
  2494. X        = (unsigned char **) alloca (2 * (stacke - stackb)
  2495. X                         * sizeof (char *));
  2496. X          bcopy (stackb, stackx, (stacke - stackb) * sizeof (char *));
  2497. X          stackp = stackx + (stackp - stackb);
  2498. X          stacke = stackx + 2 * (stacke - stackb);
  2499. X          stackb = stackx;
  2500. X        }
  2501. X      *stackp++ = 0;
  2502. X      *stackp++ = 0;
  2503. X      goto nofinalize;
  2504. X
  2505. X    case wordbound:
  2506. X      if (d == string1  /* Points to first char */
  2507. X          || d == end2  /* Points to end */
  2508. X          || (d == end1 && size2 == 0)) /* Points to end */
  2509. X        break;
  2510. X      if ((SYNTAX (d[-1]) == Sword)
  2511. X          != (SYNTAX (d == end1 ? *string2 : *d) == Sword))
  2512. X        break;
  2513. X      goto fail;
  2514. X
  2515. X    case notwordbound:
  2516. X      if (d == string1  /* Points to first char */
  2517. X          || d == end2  /* Points to end */
  2518. X          || (d == end1 && size2 == 0)) /* Points to end */
  2519. X        goto fail;
  2520. X      if ((SYNTAX (d[-1]) == Sword)
  2521. X          != (SYNTAX (d == end1 ? *string2 : *d) == Sword))
  2522. X        goto fail;
  2523. X      break;
  2524. X
  2525. X    case wordbeg:
  2526. X      if (d == end2  /* Points to end */
  2527. X          || (d == end1 && size2 == 0) /* Points to end */
  2528. X          || SYNTAX (* (d == end1 ? string2 : d)) != Sword) /* Next char not a letter */
  2529. X        goto fail;
  2530. X      if (d == string1  /* Points to first char */
  2531. X          || SYNTAX (d[-1]) != Sword)  /* prev char not letter */
  2532. X        break;
  2533. X      goto fail;
  2534. X
  2535. X    case wordend:
  2536. X      if (d == string1  /* Points to first char */
  2537. X          || SYNTAX (d[-1]) != Sword)  /* prev char not letter */
  2538. X        goto fail;
  2539. X      if (d == end2  /* Points to end */
  2540. X          || (d == end1 && size2 == 0) /* Points to end */
  2541. X          || SYNTAX (d == end1 ? *string2 : *d) != Sword) /* Next char not a letter */
  2542. X        break;
  2543. X      goto fail;
  2544. X
  2545. X#ifdef emacs
  2546. X    case before_dot:
  2547. X      if (((d - string2 <= (unsigned) size2)
  2548. X           ? d - bf_p2 : d - bf_p1)
  2549. X          <= point)
  2550. X        goto fail;
  2551. X      break;
  2552. X
  2553. X    case at_dot:
  2554. X      if (((d - string2 <= (unsigned) size2)
  2555. X           ? d - bf_p2 : d - bf_p1)
  2556. X          == point)
  2557. X        goto fail;
  2558. X      break;
  2559. X
  2560. X    case after_dot:
  2561. X      if (((d - string2 <= (unsigned) size2)
  2562. X           ? d - bf_p2 : d - bf_p1)
  2563. X          >= point)
  2564. X        goto fail;
  2565. X      break;
  2566. X
  2567. X    case wordchar:
  2568. X      mcnt = (int) Sword;
  2569. X      goto matchsyntax;
  2570. X
  2571. X    case syntaxspec:
  2572. X      mcnt = *p++;
  2573. X    matchsyntax:
  2574. X      PREFETCH;
  2575. X      if (SYNTAX (*d++) != (enum syntaxcode) mcnt) goto fail;
  2576. X      break;
  2577. X      
  2578. X    case notwordchar:
  2579. X      mcnt = (int) Sword;
  2580. X      goto matchnotsyntax;
  2581. X
  2582. X    case notsyntaxspec:
  2583. X      mcnt = *p++;
  2584. X    matchnotsyntax:
  2585. X      PREFETCH;
  2586. X      if (SYNTAX (*d++) == (enum syntaxcode) mcnt) goto fail;
  2587. X      break;
  2588. X#else
  2589. X    case wordchar:
  2590. X      PREFETCH;
  2591. X      if (SYNTAX (*d++) == 0) goto fail;
  2592. X      break;
  2593. X      
  2594. X    case notwordchar:
  2595. X      PREFETCH;
  2596. X      if (SYNTAX (*d++) != 0) goto fail;
  2597. X      break;
  2598. X#endif /* not emacs */
  2599. X
  2600. X    case begbuf:
  2601. X      if (d == string1)    /* Note, d cannot equal string2 */
  2602. X        break;        /* unless string1 == string2.  */
  2603. X      goto fail;
  2604. X
  2605. X    case endbuf:
  2606. X      if (d == end2 || (d == end1 && size2 == 0))
  2607. X        break;
  2608. X      goto fail;
  2609. X
  2610. X    case exactn:
  2611. X      /* Match the next few pattern characters exactly.
  2612. X         mcnt is how many characters to match. */
  2613. X      mcnt = *p++;
  2614. X      if (translate)
  2615. X        {
  2616. X          do
  2617. X        {
  2618. X          PREFETCH;
  2619. X          if (translate[*d++] != *p++) goto fail;
  2620. X        }
  2621. X          while (--mcnt);
  2622. X        }
  2623. X      else
  2624. X        {
  2625. X          do
  2626. X        {
  2627. X          PREFETCH;
  2628. X          if (*d++ != *p++) goto fail;
  2629. X        }
  2630. X          while (--mcnt);
  2631. X        }
  2632. X      break;
  2633. X    }
  2634. X      continue;    /* Successfully matched one pattern command; keep matching */
  2635. X
  2636. X      /* Jump here if any matching operation fails. */
  2637. X    fail:
  2638. X      if (stackp != stackb)
  2639. X    /* A restart point is known.  Restart there and pop it. */
  2640. X    {
  2641. X      if (!stackp[-2])
  2642. X        {   /* If innermost failure point is dormant, flush it and keep looking */
  2643. X          stackp -= 2;
  2644. X          goto fail;
  2645. X        }
  2646. X      d = *--stackp;
  2647. X      p = *--stackp;
  2648. X      if (d >= string1 && d <= end1)
  2649. X        dend = end_match_1;
  2650. X    }
  2651. X      else break;   /* Matching at this starting point really fails! */
  2652. X    }
  2653. X  return -1;         /* Failure to match */
  2654. X}
  2655. X
  2656. Xstatic int
  2657. Xbcmp_translate (s1, s2, len, translate)
  2658. X     unsigned char *s1, *s2;
  2659. X     register int len;
  2660. X     unsigned char *translate;
  2661. X{
  2662. X  register unsigned char *p1 = s1, *p2 = s2;
  2663. X  while (len)
  2664. X    {
  2665. X      if (translate [*p1++] != translate [*p2++]) return 1;
  2666. X      len--;
  2667. X    }
  2668. X  return 0;
  2669. X}
  2670. X
  2671. X/* Entry points compatible with bsd4.2 regex library */
  2672. X
  2673. X#ifndef emacs
  2674. X
  2675. Xstatic struct re_pattern_buffer re_comp_buf;
  2676. X
  2677. Xchar *
  2678. Xre_comp (s)
  2679. X     char *s;
  2680. X{
  2681. X  if (!s)
  2682. X    {
  2683. X      if (!re_comp_buf.buffer)
  2684. X    return "No previous regular expression";
  2685. X      return 0;
  2686. X    }
  2687. X
  2688. X  if (!re_comp_buf.buffer)
  2689. X    {
  2690. X      if (!(re_comp_buf.buffer = (char *) malloc (200)))
  2691. X    return "Memory exhausted";
  2692. X      re_comp_buf.allocated = 200;
  2693. X      if (!(re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH)))
  2694. X    return "Memory exhausted";
  2695. X    }
  2696. X  return re_compile_pattern (s, strlen (s), &re_comp_buf);
  2697. X}
  2698. X
  2699. Xint
  2700. Xre_exec (s)
  2701. X     char *s;
  2702. X{
  2703. X  int len = strlen (s);
  2704. X  return 0 <= re_search (&re_comp_buf, s, len, 0, len, 0);
  2705. X}
  2706. X
  2707. X#endif /* emacs */
  2708. X
  2709. X#ifdef test
  2710. X
  2711. X#include <stdio.h>
  2712. X
  2713. X/* Indexed by a character, gives the upper case equivalent of the character */
  2714. X
  2715. Xstatic char upcase[0400] = 
  2716. X  { 000, 001, 002, 003, 004, 005, 006, 007,
  2717. X    010, 011, 012, 013, 014, 015, 016, 017,
  2718. X    020, 021, 022, 023, 024, 025, 026, 027,
  2719. X    030, 031, 032, 033, 034, 035, 036, 037,
  2720. X    040, 041, 042, 043, 044, 045, 046, 047,
  2721. X    050, 051, 052, 053, 054, 055, 056, 057,
  2722. X    060, 061, 062, 063, 064, 065, 066, 067,
  2723. X    070, 071, 072, 073, 074, 075, 076, 077,
  2724. X    0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
  2725. X    0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
  2726. X    0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
  2727. X    0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
  2728. X    0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
  2729. X    0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
  2730. X    0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
  2731. X    0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
  2732. X    0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
  2733. X    0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
  2734. X    0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
  2735. X    0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
  2736. X    0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
  2737. X    0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
  2738. X    0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
  2739. X    0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
  2740. X    0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
  2741. X    0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
  2742. X    0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
  2743. X    0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
  2744. X    0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
  2745. X    0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
  2746. X    0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
  2747. X    0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
  2748. X  };
  2749. X
  2750. Xmain (argc, argv)
  2751. X     int argc;
  2752. X     char **argv;
  2753. X{
  2754. X  char pat[80];
  2755. X  struct re_pattern_buffer buf;
  2756. X  int i;
  2757. X  char c;
  2758. X  char fastmap[(1 << BYTEWIDTH)];
  2759. X
  2760. X  /* Allow a command argument to specify the style of syntax.  */
  2761. X  if (argc > 1)
  2762. X    obscure_syntax = atoi (argv[1]);
  2763. X
  2764. X  buf.allocated = 40;
  2765. X  buf.buffer = (char *) malloc (buf.allocated);
  2766. X  buf.fastmap = fastmap;
  2767. X  buf.translate = upcase;
  2768. X
  2769. X  while (1)
  2770. X    {
  2771. X      gets (pat);
  2772. X
  2773. X      if (*pat)
  2774. X    {
  2775. X          re_compile_pattern (pat, strlen(pat), &buf);
  2776. X
  2777. X      for (i = 0; i < buf.used; i++)
  2778. X        printchar (buf.buffer[i]);
  2779. X
  2780. X      putchar ('\n');
  2781. X
  2782. X      printf ("%d allocated, %d used.\n", buf.allocated, buf.used);
  2783. X
  2784. X      re_compile_fastmap (&buf);
  2785. X      printf ("Allowed by fastmap: ");
  2786. X      for (i = 0; i < (1 << BYTEWIDTH); i++)
  2787. X        if (fastmap[i]) printchar (i);
  2788. X      putchar ('\n');
  2789. X    }
  2790. X
  2791. X      gets (pat);    /* Now read the string to match against */
  2792. X
  2793. X      i = re_match (&buf, pat, strlen (pat), 0, 0);
  2794. X      printf ("Match value %d.\n", i);
  2795. X    }
  2796. X}
  2797. X
  2798. X#ifdef NOTDEF
  2799. Xprint_buf (bufp)
  2800. X     struct re_pattern_buffer *bufp;
  2801. X{
  2802. X  int i;
  2803. X
  2804. X  printf ("buf is :\n----------------\n");
  2805. X  for (i = 0; i < bufp->used; i++)
  2806. X    printchar (bufp->buffer[i]);
  2807. X  
  2808. X  printf ("\n%d allocated, %d used.\n", bufp->allocated, bufp->used);
  2809. X  
  2810. X  printf ("Allowed by fastmap: ");
  2811. X  for (i = 0; i < (1 << BYTEWIDTH); i++)
  2812. X    if (bufp->fastmap[i])
  2813. X      printchar (i);
  2814. X  printf ("\nAllowed by translate: ");
  2815. X  if (bufp->translate)
  2816. X    for (i = 0; i < (1 << BYTEWIDTH); i++)
  2817. X      if (bufp->translate[i])
  2818. X    printchar (i);
  2819. X  printf ("\nfastmap is%s accurate\n", bufp->fastmap_accurate ? "" : "n't");
  2820. X  printf ("can %s be null\n----------", bufp->can_be_null ? "" : "not");
  2821. X}
  2822. X#endif
  2823. X
  2824. Xprintchar (c)
  2825. X     char c;
  2826. X{
  2827. X  if (c < 041 || c >= 0177)
  2828. X    {
  2829. X      putchar ('\\');
  2830. X      putchar (((c >> 6) & 3) + '0');
  2831. X      putchar (((c >> 3) & 7) + '0');
  2832. X      putchar ((c & 7) + '0');
  2833. X    }
  2834. X  else
  2835. X    putchar (c);
  2836. X}
  2837. X
  2838. Xerror (string)
  2839. X     char *string;
  2840. X{
  2841. X  puts (string);
  2842. X  exit (1);
  2843. X}
  2844. X
  2845. X#endif /* test */
  2846. SHAR_EOF
  2847. echo "End of archive 3 (of 14)"
  2848. # if you want to concatenate archives, remove anything after this line
  2849. exit
  2850.